O Combinepdf é um modelo bacana, escrito em Pure Ruby, para analisar arquivos PDF e combiná -los (mesclar) com outros arquivos PDF, marcar a água ou carimbá -los (todos usando o formato de arquivo PDF e o código Pure Ruby).
Decidi parar de manter essa jóia e espero que alguém pudesse assumir as análises de relações públicas e a manutenção desta jóia (ou simplesmente abrir um garfo de sucesso).
Escrevi essa jóia porque precisava resolver um problema com os documentos PDF existentes em número de Bates.
No entanto, desde 2014, mantenho a jóia de graça e sem motivo, exceto que gostei de compartilhá -la com a comunidade.
Adoro essa jóia, mas não consigo mantê -la, pois tenho meus próprios projetos para me concentrar e preciso do tempo e (mais importante) o espaço -mental.
Instale com gemas rubi:
gem install combine_pdf
Resumo rápido:
Ao ler os formulários PDF, alguns dados do formulário podem ser perdidos. Tentei consertar isso da melhor maneira possível, mas não tenho certeza de que tudo funciona ainda.
Ao combinar formulários PDF, os dados do formulário podem ser unificados. Não pude consertar isso porque é assim que os formulários PDF funcionam (preenchendo um campo preenche os dados em qualquer campo com o mesmo nome), mas, francamente, eu meio que gostei do problema ... é quase um recurso.
Ao unificar os mesmos dados do TOC mais uma vez, uma das referências será unificada com a outra (o que significa que, se as páginas parecerem iguais, ambas as referências serão vinculadas à mesma página em vez de vincular a duas páginas diferentes). Você pode corrigir isso adicionando conteúdo às páginas antes de mesclar os arquivos PDF (ou seja, adicionar caixas de texto vazias a todas as páginas).
Alguns links e dados (Links de URL e PDF "Nomeados destinos") são armazenados na raiz de um PDF e eles não estão ligados de volta na página. Manter essas informações requer a fusão dos objetos em PDF, em vez de suas páginas.
Alguns links serão perdidos ao arrancar as páginas dos arquivos PDF e mesclá -los com outro PDF.
Alguns arquivos PDF criptografados (geralmente os que você não podem visualizar sem uma senha) falharão silenciosamente em vez de barulhentos. Se você preferir escolher a rota barulhenta, poderá especificar a opção raise_on_encrypted
Usando CombinePDF.load(pdf_file, raise_on_encrypted: true)
que aumentará um CombinePDF::EncryptionError
.
Às vezes, o Combinepdf aumenta uma exceção, mesmo que o PDF possa ser analisado (ou seja, quando existir conteúdo opcional em PDF) ... Acho melhor errar no lado da cautela, embora, para o conteúdo opcional, PDFs seja uma exceção evitável usando CombinePDF.load(pdf_file, allow_optional_content: true)
.
O GEM COMBINEPDF executa o código recursivo para analisar e formatar os arquivos PDF. Portanto, os arquivos PDF que aninham objetos fortemente aninhados, bem como aqueles que combinados de uma maneira que resulta em nidificação cíclica, podem explodir a pilha - resultando em uma exceção ou falha do programa.
O Combinepdf é escrito nativamente em Ruby e deve (presumivelmente) funcionar em todas as plataformas Ruby que seguem a compatibilidade do Ruby 2.0.
No entanto, os arquivos PDF são criaturas bastante complexas e nenhuma garantia é fornecida.
Por exemplo, sabe -se que os formulários de PDF têm problemas e os dados podem ser perdidos ao tentar combinar PDFs com dados de formulário preenchidos (também, formulários são objetos globais, não específicos da página, portanto, deve -se combinar todo o PDF para qualquer dados para tem alguma chance de ser preservado).
O mesmo se aplica aos links PDF e ao índice, todos com atributos globais e podem ser corrompidos ou perdidos ao combinar dados de PDF.
Se esta biblioteca causar perda de dados ou queimar sua casa, não será o culpado - conforme apontado pela licença do MIT. Dito isto, estou usando a biblioteca alegremente depois de testar contra diferentes soluções.
Para combinar arquivos PDF (ou dados):
pdf = CombinePDF . new
pdf << CombinePDF . load ( "file1.pdf" ) # one way to combine, very fast.
pdf << CombinePDF . load ( "file2.pdf" )
pdf . save "combined.pdf"
Ou mesmo um revestimento:
( CombinePDF . load ( "file1.pdf" ) << CombinePDF . load ( "file2.pdf" ) << CombinePDF . load ( "file3.pdf" ) ) . save ( "combined.pdf" )
Você também pode adicionar apenas páginas ímpares ou até mesmo:
pdf = CombinePDF . new
i = 0
CombinePDF . load ( "file.pdf" ) . pages . each do | page |
i += 1
pdf << page if i . even?
end
pdf . save "even_pages.pdf"
Observe que a adição de todas as páginas uma a uma é mais lenta do que adicionar o arquivo inteiro.
Para adicionar conteúdo às páginas PDF existentes, primeiro importe o novo conteúdo de um arquivo PDF existente. Depois disso, adicione o conteúdo a cada uma das páginas em seu PDF existente.
Neste exemplo, adicionaremos um logotipo da empresa a cada página:
company_logo = CombinePDF . load ( "company_logo.pdf" ) . pages [ 0 ]
pdf = CombinePDF . load "content_file.pdf"
pdf . pages . each { | page | page << company_logo } # notice the << operator is on a page and not a PDF object.
pdf . save "content_with_logo.pdf"
Observe que o operador << está em uma página e não em um objeto PDF. O operador << atua de maneira diferente nos objetos PDF e nas páginas.
O << Padrives do operador para garantir a injeção renomeando referências para evitar conflitos. Para a sobreposição de páginas usando dados compactados que podem não ser editáveis (devido ao suporte limitado do filtro), você pode usar:
pdf . pages ( nil , false ) . each { | page | page << stamp_page }
Adicionar números de página a um objeto ou arquivo PDF é o mais simples possível:
pdf = CombinePDF . load "file_to_number.pdf"
pdf . number_pages
pdf . save "file_with_numbering.pdf"
A numeração pode ser feita com muitas opções diferentes, com formação diferente, com ou sem um objeto de caixa e até com valores de opacidade - consulte a documentação.
Por exemplo, você preferir colocar o número da página no lado inferior direito de todas as páginas em PDF, faça:
pdf . number_pages ( location : [ :bottom_right ] )
Como outro exemplo, os traços ao redor do número são removidos e uma caixa é colocada ao redor dele. A numeração é semi-transparente e as três primeiras páginas são numeradas usando letras (a, b, c) em vez de números:
# number first 3 pages as "a", "b", "c"
pdf . number_pages ( number_format : " %s " ,
location : [ :top , :bottom , :top_left , :top_right , :bottom_left , :bottom_right ] ,
start_at : "a" ,
page_range : ( 0 .. 2 ) ,
box_color : [ 0.8 , 0.8 , 0.8 ] ,
border_color : [ 0.4 , 0.4 , 0.4 ] ,
border_width : 1 ,
box_radius : 6 ,
opacity : 0.75 )
# number the rest of the pages as 4, 5, ... etc'
pdf . number_pages ( number_format : " %s " ,
location : [ :top , :bottom , :top_left , :top_right , :bottom_left , :bottom_right ] ,
start_at : 4 ,
page_range : ( 3 ..- 1 ) ,
box_color : [ 0.8 , 0.8 , 0.8 ] ,
border_color : [ 0.4 , 0.4 , 0.4 ] ,
border_width : 1 ,
box_radius : 6 ,
opacity : 0.75 )
pdf.number_pages(number_format: " %s ", location: :bottom_right, font_size: 44)
O carregamento de dados em PDF pode ser feito no sistema de arquivos ou diretamente a partir da memória.
Carregar dados de um arquivo é fácil:
pdf = CombinePDF . load ( "file.pdf" )
Você também pode analisar arquivos PDF da memória. O carregamento da memória é especialmente eficaz para importar dados em PDF recebidos pela Internet ou de uma biblioteca de autoria diferente, como camarão:
pdf_data = prawn_pdf_document . render # Import PDF data from Prawn
pdf = CombinePDF . parse ( pdf_data )
O uso parse
também é eficaz ao carregar dados de um local remoto, contornando a necessidade de arquivos temporários desnecessários. Por exemplo:
require 'combine_pdf'
require 'net/http'
url = "https://example.com/my.pdf"
pdf = CombinePDF . parse Net :: HTTP . get_response ( URI . parse ( url ) ) . body
Da mesma forma, para carregar e analisar, a renderização também pode ser executada na memória ou em um arquivo.
Você pode emitir uma sequência de dados em PDF usando .to_pdf
. Por exemplo, para deixar um usuário baixar o PDF de um aplicativo Rails ou um aplicativo Plezi:
# in a controller action
send_data combined_file . to_pdf , filename : "combined.pdf" , type : "application/pdf"
Em Sinatra:
# in your path's block
status 200
body combined_file . to_pdf
headers 'content-type' => "application/pdf"
Se você preferir salvar os dados do PDF em um arquivo, sempre poderá usar o método save
como fizemos em nossos exemplos anteriores.
Alguns arquivos PDF contêm seções de conteúdo opcionais que nem sempre podem ser mescladas de maneira confiável. Por padrão, uma exceção é aumentada se um desses arquivos for detectado. Opcionalmente, você pode passar por um parâmetro allow_optional_content
para o PDFParser.new
, CombinePDF.load
e CombinePDF.parse
métodos:
new_pdf = CombinePDF . new
new_pdf << CombinePDF . load ( pdf_file , allow_optional_content : true )
attachments . each { | att | new_pdf << CombinePDF . load ( att , allow_optional_content : true ) }
Você pode ver uma demonstração para um "Bates Stumping Web-App" e ler seu código. Boa sorte :)
Alguns arquivos PDF são criptografados e outros são compactados (o uso de filtros) ...
Há muito pouco suporte para arquivos criptografados e suporte muito básico e limitado para arquivos compactados.
Eu preciso de ajuda com isso.
Se você quiser ajudar com o código, esteja ciente:
Eu sou um Hobbiest Gelfied de coração. A documentação está faltando e os comentários no código são diretorias ruins.
O código em si deve ser muito direto, mas fique à vontade para perguntar o que quiser.
Stefan Leitner (@sle1tner) escreveu o código de fusão de esboços que suportam PDFs que contêm um TOC.
Caige Nichols escreveu uma incrível jóia RC4 que eu usei no meu código.
Eu queria instalar a gema, mas tive problemas com a Internet e acabei copiando o código próprio no arquivo de classe Combine_PDF_Decrypt.
Crédito ao seu maravilhoso é dado aqui. Por favor, respeite sua licença e direitos autorais ... e a minha.
Mit
Você pode olhar para a página de problemas do Github e ver as tags "Help Wanted".
Se você está pensando em doações ou me enviando dinheiro - sem necessidade. Este projeto pode se sustentar sem o seu dinheiro.
O que esse projeto precisa é o tempo dado pelos desenvolvedores que o mantêm atualizado e corrigem quaisquer erros ou problemas de documentação que eles percebam ... tendo dito isso, presentes (como café grátis ou cartões -presente do iTunes) são sempre divertidos. Mas acho que existem aqueles em necessidade real que se beneficiarão mais da sua generosidade.