有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何正确合并文档?

我有以下问题,当打印合并后的pdf文件,pdf文件被切断。 有时会发生这种情况,因为文档不是8.5 x 11 它们可能是11 x 17

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

代码如下:

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

enter image description here


共 (1) 个答案

  1. # 1 楼答案

    DocumentPdfWriter类与addTemplate()方法结合使用来合并文档是个坏主意。这不是addTemplate()方法的目的。您已经显式或隐式地为正在使用的Document定义了页面大小。使用addTemplate()方法,添加PdfImportedPage实例,然后

    • 当你添加一个具有相同页面大小和旋转的新页面时,你会丢掉该页面中存在的所有互动性,但在其他方面一切都很好
    • 当添加具有不同页面大小和旋转的新页面时,将得到所描述的结果。由于大小不同,导入的页面与新页面不匹配。零件被切断,额外的边距出现,旋转不同,等等

    这些都在chapter 6 of my book中解释过。你应该使用PdfCopy而不是PdfWriter。例如,请参见FillFlattenMerge2示例:

    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示例中所做的那样:

    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示例中所做的那样

    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也会丢掉所有的互动性(链接、注释等)存在于正在合并的页面中。您的客户可能会觉得这是一个错误