4

我正在尝试编写一个 pdf 转换,它将采用包含 1-up 纵向页面的 pdf,并创建一个新文档,但将每 2 页合并为一个 2-up 横向页面

IE。

下面的代码会将内容缩小 50%,但我不知道如何制作新页面横向,同时将其他页面作为纵向注入,并注入到左上角和中心的右边

public static void main(String[] args) throws IOException, DocumentException, COSVisitorException {
    scalePages("c:/pdf/in.pdf", "c:/pdf/out" + new Date().getTime() + ".pdf", 0.50f);
}

public static void scalePages(String inFile, String outFile, float scale ) throws IOException, COSVisitorException {      
    PDDocument doc1 = null;      
    try {          
        doc1 = PDDocument.load( inFile );  
        List allPages = doc1.getDocumentCatalog().getAllPages();          
        for( int i=0; i<allPages.size(); i++ ) {              
            PDPage page1 = (PDPage)allPages.get(i ); 
            PDRectangle mediaBox = page1.getMediaBox();

            float oldX = mediaBox.getUpperRightX();
            float newX = oldX * scale;

            float oldY = mediaBox.getUpperRightY();
            float newY = oldY * scale;

            mediaBox.setUpperRightX(newX); 
            mediaBox.setUpperRightY(newY);
            PDFStreamParser parser = new PDFStreamParser(page1.getContents());              
            parser.parse();
            List tokens = parser.getTokens();              
            tokens.add(0,new COSFloat(scale));              
            tokens.add(1,new COSInteger(0));
            tokens.add(2,new COSInteger(0));
            tokens.add(3,new COSFloat(scale));             
            tokens.add(4,new COSInteger(0));
            tokens.add(5,new COSInteger(0));
            tokens.add(6,PDFOperator.getOperator("cm"));
            PDStream newContents = new PDStream( doc1 );              
            ContentStreamWriter writer = new ContentStreamWriter( newContents.createOutputStream() );
            writer.writeTokens( tokens );              
            newContents.addCompression();
            page1.setContents(newContents);
            //page1.setRotation(90);
            mediaBox.setUpperRightX(oldX);
            mediaBox.setUpperRightY(oldY);
        }          
        doc1.save( outFile );
    } finally {          
        if( doc1 != null )   {
            doc1.close();    
        }      
    }  
}

所以结果如下

任何指针将不胜感激

4

2 回答 2

7

这是一个并排“缝合”两个单页 PDF 并使用 PDFBox 将结果保存在新文件中的示例。享受!

function void generateSideBySidePDF() {
    File pdf1File = new File(FILE1_PATH);
    File pdf2File = new File(FILE2_PATH);
    File outPdfFile = new File(OUTFILE_PATH);
    PDDocument pdf1 = null;
    PDDocument pdf2 = null;
    PDDocument outPdf = null;
    try {
        pdf1 = PDDocument.load(pdf1File);
        pdf2 = PDDocument.load(pdf2File);
        outPdf = new PDDocument();

        // Create output PDF frame
        PDRectangle pdf1Frame = pdf1.getPage(0).getCropBox();
        PDRectangle pdf2Frame = pdf2.getPage(0).getCropBox();
        PDRectangle outPdfFrame = new PDRectangle(pdf1Frame.getWidth()+pdf2Frame.getWidth(), Math.max(pdf1Frame.getHeight(), pdf2Frame.getHeight()));

        // Create output page with calculated frame and add it to the document
        COSDictionary dict = new COSDictionary();
        dict.setItem(COSName.TYPE, COSName.PAGE);
        dict.setItem(COSName.MEDIA_BOX, outPdfFrame);
        dict.setItem(COSName.CROP_BOX, outPdfFrame);
        dict.setItem(COSName.ART_BOX, outPdfFrame);
        PDPage outPdfPage = new PDPage(dict);
        outPdf.addPage(outPdfPage);

        // Source PDF pages has to be imported as form XObjects to be able to insert them at a specific point in the output page
        LayerUtility layerUtility = new LayerUtility(outPdf);
        PDFormXObject formPdf1 = layerUtility.importPageAsForm(pdf1, 0);
        PDFormXObject formPdf2 = layerUtility.importPageAsForm(pdf2, 0);

        // Add form objects to output page
        AffineTransform afLeft = new AffineTransform();
        layerUtility.appendFormAsLayer(outPdfPage, formPdf1, afLeft, "left");
        AffineTransform afRight = AffineTransform.getTranslateInstance(pdf1Frame.getWidth(), 0.0);
        layerUtility.appendFormAsLayer(outPdfPage, formPdf2, afRight, "right");

        outPdf.save(outPdfFile);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (pdf1 != null) pdf1.close();
            if (pdf2 != null) pdf2.close();
            if (outPdf != null) outPdf.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
于 2015-11-18T10:53:07.510 回答
3

我最终用 itext 做这个

private String createTwoUp(String originalPdfFile) throws IOException, DocumentException {
    String newFilename = FilenameUtils.getBaseName(originalPdfFile) + "_2up." + FilenameUtils.getExtension(originalPdfFile);
    newFilename = FilenameUtils.concat(getPdfFileFolder(), newFilename);
    PdfReader reader = new PdfReader(originalPdfFile);
    Document doc = new Document(new RectangleReadOnly(842f, 595f), 0, 0, 0, 0);
    PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(newFilename));
    doc.open();
    int totalPages = reader.getNumberOfPages();
    for (int i = 1; i <= totalPages; i = i + 2) {
        doc.newPage();
        PdfContentByte cb = writer.getDirectContent();
        PdfImportedPage page = writer.getImportedPage(reader, i); // page #1

        float documentWidth = doc.getPageSize().getWidth() / 2;
        float documentHeight = doc.getPageSize().getHeight();
        if (i > 1) {
            documentHeight = documentHeight - 65f;
        }

        float pageWidth = page.getWidth();
        float pageHeight = page.getHeight();

        float widthScale = documentWidth / pageWidth;
        float heightScale = documentHeight / pageHeight;
        float scale = Math.min(widthScale, heightScale);

        //float offsetX = 50f;
        float offsetX = (documentWidth - (pageWidth * scale)) / 2;
        float offsetY = 0f;

        cb.addTemplate(page, scale, 0, 0, scale, offsetX, offsetY);

        if (i+1 <= totalPages) {

            PdfImportedPage page2 = writer.getImportedPage(reader, i+1); // page #2

            pageWidth = page.getWidth();
            pageHeight = page.getHeight();

            widthScale = documentWidth / pageWidth;
            heightScale = documentHeight / pageHeight;
            scale = Math.min(widthScale, heightScale);

            offsetX = ((documentWidth - (pageWidth * scale)) / 2) + documentWidth;

            cb.addTemplate(page2, scale, 0, 0, scale, offsetX, offsetY);
        }
    }

    doc.close();
    return newFilename;
}
于 2014-07-07T22:01:38.630 回答