Jump to content
Sign in to follow this  
David Zakary

Combining PDF files

Recommended Posts

Watched Matt Petrowsky's video on using ScriptMaster and iText to combine PDF files instead of using FileMaker's very slow Append to PDF script step.

I've tried to move the code from the example Matt provided into my code. ScriptMaster is installed and I've got the code pretty much intact from what Matt did.

For some reason it won't work. Some of the code comes across commented out (sm.exist). I'm not able to un-comment the code without getting an error.

What am I missing?

Share this post


Link to post
Share on other sites
Ocean West    104

David Here is the iText Groovy code I am using:

In my start up script just declare a variable like $RegMergePDF - to this:


RegisterGroovy( "MergePDF( files ; output )" ; "import java.io.FileOutputStream;¶

import java.util.ArrayList;¶

import java.util.List;¶

¶

import com.itextpdf.text.Document;¶

import com.itextpdf.text.pdf.PdfReader;¶

import com.itextpdf.text.pdf.PdfCopy;¶

import com.itextpdf.text.pdf.PdfImportedPage;¶

¶

try {¶

  String[] inFiles = files.split("n");¶

  int f = 0;¶

  int pageOffset = 0;¶

  String outFile = output;¶

  Document document = null;¶

  PdfCopy  writer = null;¶

¶

  while (f < inFiles.length) {¶

    // Create a reader for the next document¶

    PdfReader reader = new PdfReader(inFiles[f]);¶

    reader.consolidateNamedDestinations();¶

¶

    // Retrieve the total number of pages¶

    int n = reader.getNumberOfPages();¶

¶

    pageOffset += n;¶

¶

    // Create the master document¶

    if (f == 0) {¶

	  // step 1: Create the document-object¶

	  document = new Document(reader.getPageSizeWithRotation(1));¶

	  // step 2: Create the writer that listens to the document¶

	  writer = new PdfCopy(document, new FileOutputStream(outFile));¶

	  // step 3: Open the document¶

	  document.open();¶

    }¶

    // step 4: Add content¶

    PdfImportedPage page;¶

    for (int i = 0; i < n; ) {¶

	  ++i;¶

	  page = writer.getImportedPage(reader, i);¶

	  writer.addPage(page);¶

    }¶

¶

    f++;¶

  }¶

¶

  document.close();¶

  return outFile;¶

} catch(e) {¶

  return 'ERROR'¶

}" )

Share this post


Link to post
Share on other sites
john renfrew    30

Stephen

There are some newer convenience methods in the library, particularly for concatenation

Attached is code which will also protect bookmarks if they exist and throw an error if any of the files is password protected




RegisterGroovy( "PDFadd( filelist ; fm_fileOut ; preserve )" ; "// PDFadd ( filelist ; fm_fileOut ; preserve )¶

// 11_08_12 JR¶

// v3.0¶

// concatenate list of PDF files¶

// correctly moves any bookmarks to new pages¶

// preserve is null removes bookmarks¶

// throws PASSWORD ERROR if a file is protected¶

¶

import com.itextpdf.text.pdf.PdfConcatenate¶

import com.itextpdf.text.pdf.PdfReader¶

import com.itextpdf.text.pdf.SimpleBookmark¶

¶

files = filelist.split('n')¶

offset = 0¶

bookmarks = []¶

copy = new PdfConcatenate(new FileOutputStream(fm_fileOut), true) ¶

try {¶

files.each{item ->¶

  reader = new PdfReader("${item}")¶

  tmp = SimpleBookmark.getBookmark(reader)¶

  added = copy.addPages(reader)¶

  if (tmp){¶

   if ( offset != 0) {¶

	SimpleBookmark.shiftPageNumbers(tmp, offset, null)¶

   } //end if¶

   bookmarks.addAll(tmp)¶

  } //end if¶

  offset = offset + added¶

  } //end each¶

  if (preserve) {¶

   copy.getWriter().setOutlines(bookmarks)¶

  } //end if¶

copy.close()¶

} catch(Exception e) {¶

copy.close()¶

if (e.toString().contains('BadPassword')) { ¶

  f = new File(fm_fileOut)¶

  f.delete()¶

  return 'PASSWORD ERROR'¶

} else {¶

  return 'ERROR'¶

} //end if¶

} //end try¶

return true; isGui = false " )



Share this post


Link to post
Share on other sites
bcooney    102

btw, David, Matt uses CFs (the sm.exists is one) in his technique file.

Share this post


Link to post
Share on other sites
Ocean West    104

John,

are parameters optional?

if i were to replace this with mine i see there is a new parameter "preserve" i would have to go thru all my references and make the change.

or add the parameter - or will it default to NULL?

Share this post


Link to post
Share on other sites
john renfrew    30

Take out the ; preserve on the first line, make it MergePDF ( in both places)

Then make it if(true) instead of if(preserve) then you can use it as a direct replacement for your existing function...

It will then always process bookmarks in the output file...

Share this post


Link to post
Share on other sites

I had missed one custom function when I moved everything over. Amazing how much better it works when you have all the code. Thanks for the help everyone.

Share this post


Link to post
Share on other sites

So I finally got ScriptMaster to combine the PDF's for me. Now I have a couple of other issues...

I use SM to combine the PDF's. If the generated SM PDF file is over 20 megs - it won't open. Corrupt somehow.

So I set the PDF routine to create 100 PDF's and then SM combines the 100 into a single file, delete the 100 source files and then continue on to the next 100, combine, delete, etc.

The first combined PDF is fine. Each subsequent PDF that SM creates is only 51kb and won't open. The first combined PDF is 6.7 megs.

Anyone have any thoughts?

Share this post


Link to post
Share on other sites
john renfrew    30

Not without at least seeing your code.

Share this post


Link to post
Share on other sites
john renfrew    30

Which version of the the iText jar?

How are you creating the PDF files?

Have you tried to start with two then three etc etc to see if there is in fact a broken PDF?

What do you do with the SECOND 100 files, join them into a NEW file or try and add them to the previous one?

Have you tried the code above instead which requires the latest jar?

Does that break too?

Have you considered amending the code to write to a log file to see if anything is specifically failing?

Share this post


Link to post
Share on other sites
nleon307    0

Is anyone using iText to generate a compressed PDF since Save as PDF creates such large files especially if there are images?

Share this post


Link to post
Share on other sites
john renfrew    30

Yes I am.

I have some code that others are testing at the moment.

It takes a brute force approach by working out which dictionary entries contain image content streams, scales each one down, and converts to RGB if CMYK, and then puts the image bytes back in the same place but scaled up to the original size.

Getting down to 25% of original file size.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

×

Important Information

By using this site, you agree to our Terms of Use.