Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Unir archivos PDF (https://www.clubdelphi.com/foros/showthread.php?t=92929)

rruffino 16-03-2018 12:51:00

Unir archivos PDF
 
Hola, buen día. Necesito generar un archivo PDF cuyo contenido sea el de varios pdf mas para obtener un solo archivo pdf final. Es posible hacerlo en Delphi 7?
He estado buscando pero no he logrado conseguir lo que necesito. Si alguien tiene algún dato lo agradezco.
Saludos!!!:)

Casimiro Notevi 16-03-2018 13:29:21

Casi todos los visores de pdf tienen una opción por línea de comandos para hacer eso.
Puedes ejecutarlo desde delphi con el típico shellexecute, por ejemplo, pasándole los parámetros adecuados.

tsk 16-03-2018 16:04:50

Técnicamente puedes agarrar varios PDFs y unirlos sin necesidad de usar librerías o programas externos, ya que tu mismo puedes reconstruir la numeración de los objetos dentro del PDF y sus referencias. Si logras extraer la información de los objetos dentro del PDF y crear un árbol del objetos, te sería bastante fácil el unir varios PDFs.

Por lo general esta es la forma en que un PDF se forma

Código:

%PDF-1.0
%âãÏÓ
1 0 obj
<< /Font
<< /F0
<</Type /Font
/BaseFont /Times
/Subtype /Type1>>
>>
>>
endobj

2 0 obj
<< /Font
<< /F1
<</Type /Font
/BaseFont /Times-Italic
/Subtype /Type1>>
>>
>>
endobj

3 0 obj
<< /Kids [4 0 R 7 0 R ]
  /Type /Pages
  /Count 2
>>
endobj

4 0 obj
<<
/Rotate 0
/Parent 3 0 R
/Resources 1 0 R
/MediaBox [0.000000 0.000000 612.000000 792.000000]
/Contents [5 0 R 6 0 R ]
/Type /Page
>>
endobj
5 0 obj
<</Length 52>>
stream
BT
/F0 36 Tf
1 0 0 1 50.0 700.0 Tm
(Hola mundo)Tj
ET
endstream
endobj
6 0 obj
<</Length 80>>
stream
BT
/F0 23.0 Tf
1 0 0 1 50.0 600.0 Tm
(Primeras pruebas para unir dos PDFs.)Tj
ET
endstream
endobj
7 0 obj
<<
/Rotate 0
/Parent 3 0 R
/Resources 1 0 R
/MediaBox [0.000000 0.000000 612.000000 792.000000]
/Contents [8 0 R 9 0 R ]
/Type /Page
>>
endobj
8 0 obj
<</Length 62>>
stream
BT
/F0 36 Tf
1 0 0 1 50.0 700.0 Tm
(Hola mundo página 2)Tj
ET
endstream
endobj
9 0 obj
<</Length 65>>
stream
BT
/F0 23.0 Tf
1 0 0 1 50.0 600.0 Tm
(Hola Mundo página 2.)Tj
ET
endstream
endobj


10 0 obj
<< /Pages 3 0 R
  /Type /Catalog
>>
endobj

xref
0 11
0000000000 65535 f
0000000018 00000 n
0000000105 00000 n
0000000199 00000 n
0000000270 00000 n
0000000421 00000 n
0000000521 00000 n
0000000649 00000 n
0000000800 00000 n
0000000910 00000 n
0000001025 00000 n

trailer
<< /Root 10 0 R
/Size 11
>>
startxref
1079
%%EOF

Nota: Si el código anterior lo pones en un archivo y lo guardas como PDF, lo podrás abrir en cualquier lector de PDFs.

De cada PDF lo que te interesa extraer son los objetos

Código:

X Y obj .... endobj
Donde X es el número de objeto y Y es el generador que por lo general cuando abro un PDF siempre lo he visto en 0, así que no tengo idea para que sirve.

Con esa información puedes reconstruir un PDF con la unión de dos o más PDFs, lo que tienes que modificar es:

1.- La numeración de los objetos, que podría aplicarse sólo a renumerar los objetos que pertenzcan al segundo PDF, más no al primero.
2.- Reconstruir el catálogo de páginas
3.- Reconstruir las Referencias
4.- Reconstruir la sección xref calculando las posiciones de los objetos (offset)
5.- Reconstruir el trailer
6.- en startxref calcular el offset de la tabla xref.

Si analizamos la siguiente parte del código verás que no es del todo complejo

Código:

xref
0 11
0000000000 65535 f
0000000018 00000 n
0000000105 00000 n
0000000199 00000 n
0000000270 00000 n
0000000421 00000 n
0000000521 00000 n
0000000649 00000 n
0000000800 00000 n
0000000910 00000 n
0000001025 00000 n

trailer
<< /Root 10 0 R
/Size 11
>>
startxref
1079

La tabla de referencia siempre inicia con un 0 y la cantidad de objetos más 1, en este caso son 10+1 = 11

Código:

0 11
Después la primera entrada de la tabla es especial y es algo que siempre vas a ver en todos los PDFs
Código:

0000000000 65535 f
Después de esto viene los offset de cada objeto en orden, por ejemplo el offset del objeto 1 está en el byte 18, el objeto 2 se encuentra en el byte 105, etc.

Después de esto viene el trailer, que nos indica cual objeto es la raiz del documento PDF, más la cantidad de objetos más 1

Código:

trailer
<< /Root 10 0 R
/Size 11
>>

Si observas /Root es el objeto 10, esa R que ves ahí significa referencia

El objeto 10 me envia al catálogo de páginas

Código:

10 0 obj
<< /Pages 3 0 R
  /Type /Catalog
>>
endobj

En el cual informa cuantas páginas son y cuales son los objetos hijos que contienen esas páginas

Código:

3 0 obj
<< /Kids [4 0 R 7 0 R ]
  /Type /Pages
  /Count 2
>>
endobj

Aunque existe otra forma, y es que un PDF puede tener varios trailers, pero esa forma no la he explorado por lo que no tengo idea de como funciona.

newtron 16-03-2018 19:08:59

Hola.

Hace algunos años necesité hacer "merge" de varios pdfs y encontré esta librería, que en su versión "lite" es "free". Creo que esto te puede resolver el problema de forma fácil.

Saludos

ElKurgan 20-03-2018 07:15:49

Muy buena explicación, Tsk

Gracias y un saludo


La franja horaria es GMT +2. Ahora son las 12:45:10.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi