Java iText没有关联的PdfWriter用于进行间接

问题描述

我有以下方法that scales an image to A4

   void scale(PdfDocument pdfDocument,Rectangle pageSize,Rectangle pageBodySize) {
    int n = pdfDocument.getNumberOfPages();

    for (int i = 1; i <= n; i++) {
        PdfPage page = pdfDocument.getPage(i);

        MarginFinder marginFinder = new MarginFinder();
        PdfCanvasProcessor pdfCanvasProcessor = new PdfCanvasProcessor(marginFinder);
        pdfCanvasProcessor.processPageContent(page);
        Rectangle boundingBox = marginFinder.getBoundingBox();
        if (boundingBox == null || boundingBox.getWidth() == 0 || boundingBox.getHeight() == 0) {
            System.err.printf("Cannot scale page %d contents with bounding box %s\n",i,boundingBox);
            continue;
        } else {
            // Scale and move content into A4 with margin
            double scale = 0,xDiff = 0,yDiff = 0;
            double xScale = pageBodySize.getWidth() / boundingBox.getWidth();
            double yScale = pageBodySize.getHeight() / boundingBox.getHeight();
            if (xScale < yScale) {
                yDiff = boundingBox.getHeight() * (yScale / xScale - 1) / 2;
                scale = xScale;
            } else {
                xDiff = boundingBox.getWidth() * (xScale / yScale - 1) / 2;
                scale = yScale;
            }

            AffineTransform transform = AffineTransform.getTranslateInstance(pageBodySize.getLeft() + xDiff,pageBodySize.getBottom() + yDiff);
            transform.scale(scale,scale);
            transform.translate(-boundingBox.getLeft(),-boundingBox.getBottom());

            new PdfCanvas(page.newContentStreamBefore(),page.getResources(),pdfDocument)
                    .concatMatrix(transform);

        }
        page.setMediaBox(pageSize);
        page.setCropBox(pageSize);
    }
}

此代码段中将调用/调用此方法:

  ByteArrayOutputStream mergedPdfStream = new ByteArrayOutputStream();
    PdfDocument mergedPdf = new PdfDocument(new PdfWriter(mergedPdfStream));

    for (PdfDocument doc : pdfDocuments) {
        int n = doc.getNumberOfPages();
      
        for (int i = 1; i <= n; i++) {
       
            PdfPage page = doc.getPage(i).copyTo(mergedPdf);
            mergedPdf.addPage(page);
          
        }
        Rectangle pageSize = PageSize.A4;
        Rectangle pageBodySize = pageSize.clone().applyMargins(72,72,false);
        scale(doc,pageSize,pageBodySize);
    }

   

    mergedPdf.close();

但是,当它最后执行此代码时

 new PdfCanvas(page.newContentStreamBefore(),pdfDocument)
                .concatMatrix(transform);

它引发PDF异常没有关联的PdfWriter用于进行间接调用:

 com.itextpdf.kernel.PdfException: There is no associate PdfWriter for making indirects.
at com.itextpdf.kernel.pdf.PdfObject.makeIndirect(PdfObject.java:228) ~[kernel-7.1.1.jar:?]
at com.itextpdf.kernel.pdf.PdfObject.makeIndirect(PdfObject.java:248) ~[kernel-7.1.1.jar:?]
at com.itextpdf.kernel.pdf.PdfPage.newContentStream(PdfPage.java:1186) ~[kernel-7.1.1.jar:?]
at com.itextpdf.kernel.pdf.PdfPage.newContentStreamBefore(PdfPage.java:244) ~[kernel-7.1.1.jar:?]

如何解决此问题?我做错什么了吗?

解决方法

您致电

scale(doc,pageSize,pageBodySize);

对于PdfDocument doc中的每个pdfDocuments。因此,将页面复制到mergedPdf后,您将尝试缩放源文档中的页面 。您无法缩放源PdfDocument实例中的页面,因为它们是只读打开的(即仅使用PdfReader,而没有PdfWriter),然后在之后执行em>复制也没有意义,因为您确定要缩放结果mergedPdf中的内容,而不是源中的内容。

因此,移动方块

Rectangle pageSize = PageSize.A4;
Rectangle pageBodySize = pageSize.clone().applyMargins(72,72,false);
scale(doc,pageBodySize);

从外部for循环主体中移出,然后用最后一行替换

scale(mergedPdf,pageBodySize);

缩放生成的合并PDF。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...