Java iText没有用于进行间接调用的关联PdfWriter [英] Java iText There is no associate PdfWriter for making indirects

查看:278
本文介绍了Java iText没有用于进行间接调用的关联PdfWriter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下方法将图像缩放到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);
    }
}

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

This method is invoked/called in this snippet :

  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, 72, 72, false);
        scale(doc, pageSize, pageBodySize);
    }

   

    mergedPdf.close();

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

However , when it performs this code at the end

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

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

It throws an PDF Exception There is no associate PdfWriter for making indirects:

 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:?]

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

How can I fix this problem? Am I doing something wrong ?

推荐答案

您致电

scale(doc, pageSize, pageBodySize);

中每个PdfDocument doc

.因此,将页面复制mergedPdf后,您尝试缩放源文档中的页面 .您无法缩放源PdfDocument实例中的页面,因为它们是只读打开的(即仅使用PdfReader,而没有PdfWriter),并且在复制后 也不这样做.毫无疑问,因为您确定要缩放结果mergedPdf中的内容,而不是源中的内容.

for each PdfDocument doc in pdfDocuments. So after copying the pages to mergedPdf you try to scale the pages in your source documents. You cannot scale the pages in your source PdfDocument instances as they are opened read-only (i.e. only with a PdfReader, without a PdfWriter), and doing so after copying also doesn't make sense as you surely want to scale what's in the result mergedPdf, not in the sources.

因此,移动方块

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

在外部for循环主体中的

之后,然后将最后一行替换为

out of the outer for loop body, after it, and replace the last line by

scale(mergedPdf, pageSize, pageBodySize);

缩放生成的合并PDF.

to scale the resulting merged PDF.

这篇关于Java iText没有用于进行间接调用的关联PdfWriter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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