3

I'm trying to set Creation Date & Modified Date in the Superimposing content from one PDF into another PDF example sandbox.stamper.SuperImpose.java.

The principle is (I think) clear:

use getInfo() & then do

info.put(PdfName.CREATIONDATE, new PdfDate(calendar));

or

info.put("CreationDate", "D:20160508090344+02'00'");

depending on whether a HashMap<String, String> or PdfDictionary is available.

But where? I just can't quite seem to find the right place to insert the code... I'm also having trouble overwriting the original Title attribute.

kayess
  • 3,384
  • 9
  • 28
  • 45
Dave The Dane
  • 650
  • 1
  • 7
  • 18
  • The creation date is the creation date. iText assumes that changing that date is an act of forgery and doesn't allow it. The modification date is the modification date. iText assumes that using any date other that the current date is an act of forgery and doesn't allow it. – Bruno Lowagie May 09 '16 at 09:14
  • ok, that makes some sense. Bit of a shame, as the original document in this case is really just a template. Why can't I change the Title? (I was able to add a Subject) – Dave The Dane May 09 '16 at 10:16
  • Changing the title should be no problem. I also checked the recent code, and I saw no indication that the "CreationDate" couldn't be changed, so that may have changed somewhere in the history of iText. Only the modification date can't be changed: the current date is used. – Bruno Lowagie May 09 '16 at 10:43
  • Important note: if the document contains XMP metadata, you need to change the XMP metadata too. Recent versions of Adobe Reader give preference to the data stored in the XMP over the data stored in the info dictionary. – Bruno Lowagie May 09 '16 at 10:44
  • ok, thanks very much for that Info. I'll check the XMP metadata. could you give me a hint where in Superimpose.java would be the correct place to insert the code? I was also going to ask if PdfReader.unethical = true would help :) – Dave The Dane May 09 '16 at 11:15
  • I was already working on an example. I've added that example in my answer. – Bruno Lowagie May 09 '16 at 11:17

1 Answers1

2

Please take a look at the following files state.pdf and state_metadata.pdf.

The metadata of the former looks like this:

enter image description here

The metadata of the latter looks like this:

enter image description here

You can see that the title and the dates have changed.

Now take a look at the ChangeMetadata example to find out how this was done:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    Map info = reader.getInfo();
    info.put("Title", "New title");
    info.put("CreationDate", new PdfDate().toString());
    stamper.setMoreInfo(info);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    XmpWriter xmp = new XmpWriter(baos, info);
    xmp.close();
    stamper.setXmpMetadata(baos.toByteArray());
    stamper.close();
    reader.close();
}

Changing the title is easy:

info.put("Title", "New title");

Changing the creation date requires that you use a specific date format, which is why I used the PdfDate object:

info.put("CreationDate", new PdfDate().toString());

Old versions of iText may not allow the creation date to be changed, so please make sure you're using a recent iText version.

The modification date is changed automatically. The current date is used and you can't override this.

The following lines only change the metadata in the Info dictionary:

Map info = reader.getInfo();
info.put("Title", "New title");
info.put("CreationDate", new PdfDate().toString());
stamper.setMoreInfo(info);

If you use an old version of Adobe Reader, you will see the change, but more recent PDF viewers give preference to the metadata stored in the XMP metadata stream. This means that you also have to create a new XMP stream:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
XmpWriter xmp = new XmpWriter(baos, info);
xmp.close();
stamper.setXmpMetadata(baos.toByteArray());

When you say that you've changed the title in the info dictionary and that you don't see the change, you should try changing the XMP metadata too. A PDF with two different sets of metadata that contradict each other is considered being an invalid PDF in some cases (e.g. when you need to meet PDF/A compliance).

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • ok, thanks very much for all that. In the mean time, I turned off XMP metadata creation by commenting out stamper.createXmpMetadata(); & was able to change Creation Date & most of the other metadata, but Modification Date was still putting up some resistance :) So now I'll try out the XMP metadata stuff you suggested above. Thanks again. – Dave The Dane May 09 '16 at 11:46
  • Modification Date will always be set automatically to the current date and time on your system. – Bruno Lowagie May 09 '16 at 11:47
  • Hmmm, maybe a case for `PdfStamper.unethical = true;` or something similar. Anyway, I've now fixed it to write both the old Info & the new XMP stuff & everything is hunky dory. And if I'm feeling really "unethical" I can just set the machine time :) Many, many thanks. – Dave The Dane May 09 '16 at 12:32
  • 1
    Consider yourself honoured :-) – Dave The Dane May 09 '16 at 13:09