如何正确合并文档? [英] How to merge documents correctly?

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

问题描述

我在合并后打印pdf文件时遇到以下问题,pdf文件被截断.有时发生这种情况是因为文档不是 8.5 x 11它们可能像 11 x 17.

I have the following problem when printing the pdf file after merge, the pdf documents get cut off. Sometimes this happens because the documents aren't 8.5 x 11 they might be like 11 x 17.

我们可以让它检测页面大小,然后对这些文档使用相同的页面大小吗?或者,如果没有,是否可以让它适合页面?

Can we make it detect the page size and then use that same page size for those documents? Or, if not, is it possible to have it fit to page?

代码如下:

package com.sumit.program;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;

public class MergePdf {

    public static void main(String[] args) {
        try {
            List<InputStream> pdfs = new ArrayList<InputStream>();

            pdfs.add(new FileInputStream("C:\Documents and Settings\Sumit\Desktop\NewEcnProject\Document1.pdf"));
            pdfs.add(new FileInputStream("C:\Documents and Settings\Sumit\Desktop\NewEcnProject\Landscape.pdf"));           
            OutputStream output = new FileOutputStream("C:\Documents and Settings\Sumit\Desktop\NewEcnProject\merge1.pdf");
            MergePdf.concatPDFs(pdfs, output, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void concatPDFs(List<InputStream> streamOfPDFFiles,
            OutputStream outputStream, boolean paginate) {

        Document document = new Document();
        try {
            List<InputStream> pdfs = streamOfPDFFiles;
            List<PdfReader> readers = new ArrayList<PdfReader>();
            int totalPages = 0;
            Iterator<InputStream> iteratorPDFs = pdfs.iterator();

            // Create Readers for the pdfs.
            int i=1;
            while (iteratorPDFs.hasNext()) {
                InputStream pdf = iteratorPDFs.next();
                PdfReader pdfReader = new PdfReader(pdf);
                System.out.println("Page size is "+pdfReader.getPageSize(1));
                readers.add(pdfReader);
                totalPages += pdfReader.getNumberOfPages();
                i++;
            }
            // Create a writer for the outputstream
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            writer.setCompressionLevel(9);
            document.open();
            BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
                    BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            PdfContentByte cb = writer.getDirectContent(); // Holds the PDF data

            PdfImportedPage page;
            int currentPageNumber = 0;
            int pageOfCurrentReaderPDF = 0;
            Iterator<PdfReader> iteratorPDFReader = readers.iterator();

            // Loop through the PDF files and add to the output.
            while (iteratorPDFReader.hasNext()) {
                PdfReader pdfReader = iteratorPDFReader.next();

                // Create a new page in the target for each source page.
                System.out.println("No. of pages "+pdfReader.getNumberOfPages());
               i=0;
                while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
                    Rectangle r=pdfReader.getPageSize(pdfReader.getPageN(pageOfCurrentReaderPDF+1));
                    if(r.getWidth()==792.0 && r.getHeight()==612.0)
                        document.setPageSize(PageSize.A4.rotate());
                    else
                        document.setPageSize(PageSize.A4);
                    document.newPage();
                    pageOfCurrentReaderPDF++;
                    currentPageNumber++;
                    i++;

                    page = writer.getImportedPage(pdfReader,
                            pageOfCurrentReaderPDF);
                    System.out.println("Width is "+page.getWidth());
                    System.out.println("Height is "+page.getHeight());
                    cb.newlineText();
                    cb.addTemplate(page, 0, 0);

                    // Code for pagination.
                    if (paginate) {
                        cb.beginText();
                        cb.setFontAndSize(bf, 9);
                        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, ""
                                + currentPageNumber + " of " + totalPages, 520,
                                5, 0);
                        cb.endText();
                    }
                }
                pageOfCurrentReaderPDF = 0;
            }
            outputStream.flush();
            document.close();
            outputStream.close();
            System.out.println("Merging of Pdfs is done.......");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (document.isOpen())
                document.close();
            try {
                if (outputStream != null)
                    outputStream.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }
}

推荐答案

结合使用 DocumentPdfWriter 类与 addTemplate() 类> 合并文档的方法是个坏主意.这不是 addTemplate() 方法的用途.您已经明确或隐含地定义了您正在使用的 Document 的页面大小.使用 addTemplate() 方法,您添加 PdfImportedPage 实例,以及

Using the Document and PdfWriter class in combination with the addTemplate() method to merge documents is a bad idea. That's not what the addTemplate() method is meant for. You have explicitly or implicitly defined the page size for the Document you are working with. With the addTemplate() method, you add PdfImportedPage instances, and

  • 当您添加具有相同页面大小和旋转的新页面时,您会丢弃该页面中存在的所有交互性,但其他一切都很好,
  • 当您添加具有不同页面大小和旋转的新页面时,您会得到您所描述的结果.由于大小不同,导入的页面和新的页面不匹配.部分被切断、出现额外的边距、旋转不同等.

这在我的书的第 6 章中都有解释.您应该使用 PdfCopy 而不是 PdfWriter.例如,参见 FillFlattenMerge2 示例:

This is all explained in chapter 6 of my book. You should use PdfCopy instead of PdfWriter. See for instance the FillFlattenMerge2 example:

Document document = new Document();
PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
document.open();
PdfReader reader;
String line = br.readLine();
// loop over readers
    // add the PDF to PdfCopy
    reader = new PdfReader(baos.toByteArray());
    copy.addDocument(reader);
    reader.close();
// end loop
document.close();

在您的情况下,您还需要添加页码,您可以在第二次执行此操作,就像在 StampPageXofY 示例:

In your case, you also need to add page numbers, you can do this in a second go, as is done in the StampPageXofY example:

PdfReader reader = new PdfReader(src);
int n = reader.getNumberOfPages();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
PdfContentByte pagecontent;
for (int i = 0; i < n; ) {
    pagecontent = stamper.getOverContent(++i);
    ColumnText.showTextAligned(pagecontent, Element.ALIGN_RIGHT,
            new Phrase(String.format("page %s of %s", i, n)), 559, 806, 0);
}
stamper.close();
reader.close();

或者您可以在合并时添加它们,就像在 MergeWithToc 示例中所做的那样.>

Or you can add them while merging, as is done in the MergeWithToc example.

Document document = new Document();
PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename));
PageStamp stamp;
document.open();
int n;
int pageNo = 0;
PdfImportedPage page;
Chunk chunk;
for (Map.Entry<String, PdfReader> entry : filesToMerge.entrySet()) {
    n = entry.getValue().getNumberOfPages();
    for (int i = 0; i < n; ) {
        pageNo++;
        page = copy.getImportedPage(entry.getValue(), ++i);
        stamp = copy.createPageStamp(page);
        chunk = new Chunk(String.format("Page %d", pageNo));
        if (i == 1)
            chunk.setLocalDestination("p" + pageNo);
        ColumnText.showTextAligned(stamp.getUnderContent(),
                Element.ALIGN_RIGHT, new Phrase(chunk),
                559, 810, 0);
        stamp.alterContents();
        copy.addPage(page);
    }
}
document.close();
for (PdfReader r : filesToMerge.values()) {
    r.close();
}
reader.close();

我强烈建议不要使用 PdfWriter 来合并文档!如果您在 Document 类中更改页面大小和页面的旋转,这并非不可能,但您自己会变得更难.此外:使用 PdfWriter 还会丢弃您正在合并的页面中存在的所有交互性(链接、注释等).您的客户可能会认为这是一个错误.

I strongly advise against using PdfWriter to merge documents! It's not impossible if you change the page size and the rotation of the page in the Document class, but you're making it harder on yourself. Moreover: using PdfWriter also throws away all interactivity (links, annotations,...) that exists in the pages you're merging. Your customer may experience that as a bug.

这篇关于如何正确合并文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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