سؤال

I'm using iText library to create and add data to a PDF.

I want to add some textLines and an image to the PDF more than once until i close the file.

 numOfSamples = timeIHitTheButton();
.
.
.
 *a loop tha call it the number of times choosen by numOfSamples*
 DSM.saveData();

The DataStore (DSM is a DataStore instance) class creates the Document doc.pdf correctly and DSM.addText() and DSM.addPicture() prints correctly three textlines an an image on the file, but only if I press the button just once !!

I WANT TO WRITE THE SAME STRING AND AN IMAGE EVERY TIME I PRESS THE BUTTON (if I press it once i have one sample, if trwice i have two samples etc). IF I PRESS IT JUST ONCE AND I TERMINATE, I GET MY PDF WITH THE STRING AND THE PICTURES, BUT IF I PRESS IT MORE THAN ONCE, I GOT AN UNREADABLE AND DAMAGED PDF FILE. I DON'T KNOW WHY. HOW CAN I CONTINUE WRITIN A PICTURE AND THE STRING CONTINUOSLY UNTIL THE NUMBER OF SAMPLES IS FINISHED?

Here i post some code if useful ("newPic1.jpg" "newPic2.jpg" etc are the stored pictures to add to the PDF togheter with the text.):

public class DataStore{ ....
.
.
.

public DataStore(String Str1, String Str2, String Str3, int numOfSemples) 
        throws Exception{

    document = new Document();
    String1 = str1;
    String2 = str2;
    String3 = str3;
    Samples = numOfSemples;

    document.open();
}


privatevoid saveData(){

    if(!created){
        this.createFile();
        created=true;
    }
    this.addText();
    this.addPicture();
}
private void createFile(){

    try {
        OutputStream file = new FileOutputStream(
                new File("Doc.pdf"));
        PdfWriter.getInstance(document, file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (DocumentException e) {
        e.printStackTrace();
    }
}

private void addText(){

    try {
        if(Samples > 0)
        document.open();
        document.add(new Paragraph(Double.toString(String1)));
        document.add(new Paragraph(Double.toString(String2)));
        document.add(new Paragraph(Double.toString(String3)));
    } catch (DocumentException e) {
        e.printStackTrace();
    }
}

private void addPicture(){

    try {
        Image img = Image.getInstance("NewPic" + Samples + ".jpg");
        document.add(img);
    } catch (BadElementException bee) {
        bee.printStackTrace();
    } catch (MalformedURLException mue) {
        mue.printStackTrace();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    } catch (DocumentException dee) {
        dee.printStackTrace();
    }
    if(Samples == 0)
        document.close();
            else Samples--;
}
}
هل كانت مفيدة؟

المحلول

You use iText commands in the wrong order:

  • Your DataStore constructor creates a new Document and calls its open method (which is too early as there is no writer yet).
  • Some time later, in the first saveData call, you call createFile which creates the PdfWriter.
  • In all saveData calls addText is called which for Samples > 0 opens the document again each time (which is ok at the first time but shall not be done multiple times).
  • Eventually, in the saveData call with Samples == 0 you close the document.

Thus, in essence you do this:

document = new Document();
document.open();
[...]
PdfWriter.getInstance(document, file);
[...]
[for `Samples` times]
    document.open();
    [add some paragraphs]
    [add an image]
[end for]
document.close();

Compare this to how it should be done:

// step 1
Document document = new Document();
// step 2
PdfWriter.getInstance(document, new FileOutputStream(filename));
// step 3
document.open();
// step 4
[add content to the PDF]
// step 5
document.close();

(copied from the HelloWorld.java sample from iText in Action — 2nd Edition)

Only for Samples == 1 you have it about right (the superfluous document.open() in the constructor being ignored as there is no writer yet); for larger values of Samples, though, you open the document multiple times with a writer present which will likely append a PDF start over and over again to the output stream.

Quite likely you can fix the issue by removing all your current document.open() calls (including the if(Samples > 0) in addText()) and add one in createFile() right after PdfWriter.getInstance(document, file).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top