iText的合并与acrofields文件 [英] IText merge documents with acrofields

查看:2355
本文介绍了iText的合并与acrofields文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在有一个PdfReader,而且我填写的acrofields与PdfStamper。我现在有另一个PDF复制到的这种形式,我一直填写结束,只有这样,我失去了新的形式我复制过来的acrofield。这里是code。

I currently have a PdfReader and a PdfStamper that I am filling out the acrofields with. I now have to copy another pdf to the end of that form I have been filling out and when I do I lose the acrofield on the new form I copy over. Here is the code.

public static void addSectionThirteenPdf(PdfStamper stamper, Rectangle pageSize, int pageIndex){
     PdfReader reader = new PdfReader(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/resources/documents/Section13.pdf"));
     AcroFields fields = reader.getAcroFields();

     fields.renameField("SecurityGuidancePage3", "SecurityGuidancePage" + pageIndex);

     stamper.insertPage(pageIndex, pageSize);
     stamper.replacePage(reader, 1, pageIndex);
}

这是我创建的原始文件的方法是这样的。

The way that I am creating the original document is like this.

     OutputStream output = FacesContext.getCurrentInstance().getExternalContext().getResponseOutputStream();

     PdfReader pdfTemplate = new PdfReader(FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/resources/documents/dd254.pdf"));

     PdfStamper stamper = new PdfStamper(pdfTemplate, output);
     stamper.setFormFlattening(true);

     AcroFields fields = stamper.getAcroFields();

有没有办法合并使用的第一块code和两个acrofields的合并在一起?

Is there a way to merge using the first piece of code and merge both of the acrofields together?

推荐答案

根据你想要的东西,不同的情况是可能的,但在任何情况下:你这样做是错误的。您应该使用 PdfCopy PdfSmartCopy 来合并文档。

Depending on what you want exactly, different scenarios are possible, but in any case: you are doing it wrong. You should use either PdfCopy or PdfSmartCopy to merge documents.

在不同的场景将在以下视频教程的解释。

The different scenarios are explained in the following video tutorial.

您可以发现,大部分的在 iText的沙箱的例子。

You can find most of the examples in the iText sandbox.

合并不同的形式(具有不同的字段)

如果要合并的不同的的形式而不压扁他们,你应该使用 PdfCopy 如在的 MergeForms 例如:

If you want to merge different forms without flattening them, you should use PdfCopy as is done in the MergeForms example:

public void createPdf(String filename, PdfReader[] readers) throws IOException, DocumentException {
    Document document = new Document();
    PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename));
    copy.setMergeFields();
    document.open();
    for (PdfReader reader : readers) {
        copy.addDocument(reader);
    }
    document.close();
    for (PdfReader reader : readers) {
        reader.close();
    }
}

在这种情况下,读者 PdfReader 包含的不同的的形式实例数组(不同的字段名),因此我们使用 PdfCopy 我们确保我们不要忘了使用 setMergeFields()方法,或字段将不会被复制。

In this case, readers is an array of PdfReader instances containing different forms (with different field names), hence we use PdfCopy and we make sure that we don't forget to use the setMergeFields() method, or the fields won't be copied.

合并相同的形式(有相同的字段)

在这种情况下,我们需要重命名字段,因为我们可能需要在不同的页面不同的值。在PDF中,字段只能有一个值。如果合并相同的形式,你有相同域的多个可视化,但是的每个可视化显示相同的值的(因为在现实中,只有一个字段)。

In this case, we need to rename the fields, because we probably want different values on different pages. In PDF a field can only have a single value. If you merge identical forms, you have multiple visualizations of the same field, but each visualization will show the same value (because in reality, there is only one field).

让我们一起来看看 MergeForms2 例如:

Let's take a look at the MergeForms2 example:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    Document document = new Document();
    PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
    copy.setMergeFields();
    document.open();
    List<PdfReader> readers = new ArrayList<PdfReader>();
    for (int i = 0; i < 3; ) {
        PdfReader reader = new PdfReader(renameFields(src, ++i));
        readers.add(reader);
        copy.addDocument(reader);
    }
    document.close();
    for (PdfReader reader : readers) {
        reader.close();
    }
}

public byte[] renameFields(String src, int i) throws IOException, DocumentException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PdfReader reader = new PdfReader(src);
    PdfStamper stamper = new PdfStamper(reader, baos);
    AcroFields form = stamper.getAcroFields();
    Set<String> keys = new HashSet<String>(form.getFields().keySet());
    for (String key : keys) {
        form.renameField(key, String.format("%s_%d", key, i));
    }
    stamper.close();
    reader.close();
    return baos.toByteArray();
}

正如你所看到的, renameFields()方法,在内存中创建一个新文档。该文件合并使用其他文件 PdfSmartCopy 。如果你会使用 PdfCopy 在这里,你的文档会臃肿(我们很快就会找到答案)。

As you can see, the renameFields() method creates a new document in memory. That document is merged with other documents using PdfSmartCopy. If you'd use PdfCopy here, your document would be bloated (as we'll soon find out).

合并扁平形式

FillFlattenMerge1 ,我们填写使用表格 PdfStamper 。其结果是,保存在内存中,并正在使用合并 PdfCopy 的PDF文件。虽然这个例子是好的,如果你想合并不同的形式,这其实是在怎么不去做(如的视频教程)。

In the FillFlattenMerge1, we fill out the forms using PdfStamper. The result is a PDF file that is kept in memory and that is merged using PdfCopy. While this example is fine if you'd merge different forms, this is actually an example on how not to do it (as explained in the video tutorial).

借助 FillFlattenMerge2 演示如何合并所填写正确扁平相同的形式:

The FillFlattenMerge2 shows how to merge identical forms that are filled out and flattened correctly:

public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
    Document document = new Document();
    PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
    document.open();
    ByteArrayOutputStream baos;
    PdfReader reader;
    PdfStamper stamper;
    AcroFields fields;
    StringTokenizer tokenizer;
    BufferedReader br = new BufferedReader(new FileReader(DATA));
    String line = br.readLine();
    while ((line = br.readLine()) != null) {
        // create a PDF in memory
        baos = new ByteArrayOutputStream();
        reader = new PdfReader(SRC);
        stamper = new PdfStamper(reader, baos);
        fields = stamper.getAcroFields();
        tokenizer = new StringTokenizer(line, ";");
        fields.setField("name", tokenizer.nextToken());
        fields.setField("abbr", tokenizer.nextToken());
        fields.setField("capital", tokenizer.nextToken());
        fields.setField("city", tokenizer.nextToken());
        fields.setField("population", tokenizer.nextToken());
        fields.setField("surface", tokenizer.nextToken());
        fields.setField("timezone1", tokenizer.nextToken());
        fields.setField("timezone2", tokenizer.nextToken());
        fields.setField("dst", tokenizer.nextToken());
        stamper.setFormFlattening(true);
        stamper.close();
        reader.close();
        // add the PDF to PdfCopy
        reader = new PdfReader(baos.toByteArray());
        copy.addDocument(reader);
        reader.close();
    }
    br.close();
    document.close();
}

这些三种情况。你的问题是太不清楚的人,但你要决定哪些场景是您需要的最合适的。我建议你​​花时间去学习你code之前。观看视频,请尝试的例子,如果你还有疑问,您就可以发布一个更聪明的问题。

These are three scenarios. Your question is too unclear for anyone but you to decide which scenario is the best fit for your needs. I suggest that you take the time to learn before you code. Watch the video, try the examples, and if you still have doubts, you'll be able to post a smarter question.

这篇关于iText的合并与acrofields文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆