0

I would like to set attributes to pdf before uploading it into a server.

Document document = new Document();
try
{
    OutputStream file = new FileOutputStream({Localpath});
    PdfWriter.getInstance(document, file);
    document.open();

    //Set attributes here
    document.addTitle("TITLE");


    document.close();
    file.close();           
} catch (Exception e)
{
    e.printStackTrace();
} 

But its not working. The file is getting corrupted

mkl
  • 90,588
  • 15
  • 125
  • 265
Jaya Lakshmi
  • 57
  • 1
  • 3
  • 12
  • Your code obviously tries to create a new document from scratch. But you add no content at all, so it fails. Have you merely forgotten to add content? Or do you actually manipulate an existing document? In the latter case you would work with a `PdfReader` and `PdfStamper` couple. – mkl Apr 20 '17 at 09:38
  • @mkl. I tried with PDFReader and PdfStamper. The problem here is PdfStamper creates a new pdf file. So just to add attributes in existing pdf I dont want to read the entire file and create a new file. – Jaya Lakshmi Apr 20 '17 at 09:59
  • iText does not allow in-place manipulation of files. – mkl Apr 20 '17 at 10:02
  • Thanks @mkl. Is there any other API in java 7 to do in place manipulation of files? – Jaya Lakshmi Apr 20 '17 at 10:05
  • What exactly do you want to prevent? The (temporary) existence of a second file? Or the memory requirement for loading the whole original file at once into memory. Either one or the other item can be prevented using iText but not both at the same time. – mkl Apr 20 '17 at 10:14
  • @mkl . Temporary existence of second file – Jaya Lakshmi Apr 20 '17 at 10:21
  • Cf. the edit to my answer, it shows how to prevent a second, temporary file. – mkl Apr 20 '17 at 11:09

1 Answers1

0

In a comment to another answer the OP clarified:

I want to set attributes to an existing pdf(not to create new pdf)

Obviously, though, his code creates a new document from scratch (as is obvious from the fact that a mere FileOutputStream is used to access the file, no reading, only writing).

To manipulate an existing PDF, one has to use a PdfReader / PdfWriter couple. Bruno Lowagie provided an example for that in his answer to the stack overflow question "iText setting Creation Date & Modified Date in sandbox.stamper.SuperImpose.java":

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();
}

(ChangeMetadata.java)

As you see the code sets the metadata both in the ol'fashioned PDF info dictionary (stamper.setMoreInfo) and in the XMP metadata (stamper.setXmpMetadata).

Obviously src and dest should not be the same here.

Without a second file

In yet another comment the OP clarified that he had already tried a similar solution but that he wants to prevent the

Temporary existence of second file

This can easily be prevented by first reading the original PDF into a byte[] and then stamping to it as the target file. E.g. if File singleFile references the original file which is also to be the target file, you can implement:

byte[] original = Files.readAllBytes(singleFile.toPath());

PdfReader reader = new PdfReader(original);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(singleFile));
Map<String, String> 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();

(UpdateMetaData test testChangeTitleWithoutTempFile)

Community
  • 1
  • 1
mkl
  • 90,588
  • 15
  • 125
  • 265
  • This code doesnt work if the destination pdf file contains only images. – Jaya Lakshmi Apr 20 '17 at 10:20
  • @JayaLakshmi *"doesnt work if the destination pdf file contains only images"* - that is wrong, I tested it with such a file and it worked alright. Probably you have certain files with only images which actually have some other, unrelated attribute in common which results in an issue. In that case please share such a file. – mkl Apr 20 '17 at 10:34