1

我正在使用 iText 库创建数据并将其添加到 PDF。

在关闭文件之前,我想多次向 PDF 添加一些 textLines 和图像。

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

DataStore(DSM 是一个 DataStore 实例)类正确地创建了 Document doc.pdf,并且 DSM.addText() 和 DSM.addPicture() 在文件上正确打印了三个文本行和一个图像,但前提是我只按一次按钮! !

每次按下按钮时,我都想写相同的字符串和图像(如果我按下它一次我有一个样本,如果我按下它两次我有两个样本等)。如果我只按一次并终止,我会得到带有字符串和图片的 PDF,但如果我按多次,我会得到一个无法读取和损坏的 PDF 文件。我不知道为什么。我怎样才能继续写图片和字符串,直到样本数量完成?

如果有用的话,我在这里发布一些代码(“newPic1.jpg”“newPic2.jpg”等是存储的图片与文本一起添加到 PDF。):

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--;
}
}
4

1 回答 1

3

您以错误的顺序使用 iText 命令:

  • 您的DataStore构造函数创建一个新的Document并调用它的open方法(这还为时过早,因为还没有编写器)。
  • 一段时间后,在第一次saveData调用中,您调用createFile创建PdfWriter.
  • 在所有saveData调用addText中,Samples > 0每次都会再次打开文档(第一次可以,但不应多次执行)。
  • 最终,在saveData与您通话时Samples == 0关闭文档。

因此,本质上你这样做:

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

将此与应如何完成进行比较:

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

(复制自iText in Action - 2nd Edition 中的HelloWorld.java示例)

只有Samples == 1你有它的权利(document.open()构造函数中多余的被忽略,因为还没有编写器);但是,对于较大的值Samples,,您可以在存在作家的情况下多次打开文档,这可能会一遍又一遍地将 PDF 开头附加到输出流中。

您很可能可以通过删除所有当前document.open()调用(包括if(Samples > 0)in )并在之后addText()添加一个 in来解决问题createFile()PdfWriter.getInstance(document, file).

于 2013-05-28T08:20:32.330 回答