将页码文本添加到 pdf 副本会使用 itext 7 进行翻转/镜像

问题描述 投票:0回答:2

所以...我一直在尝试使用itext文档中提供的示例来合并文档并为合并结果创建目录。但是向每个页面添加页码文本的部分并没有像我预期的那样工作。发生的情况是添加的文本在某个水平轴上翻转,如下图所示:

enter image description here

此外,用于为添加的文本设置固定位置的方法的java文档(

public T setFixedPosition(int pageNumber, float left, float bottom, float width)
)对我来说没有意义:

设置元素绝对重新定位的值。指定的坐标对应于元素的左下角,并且它向上生长。

但是当我运行

setFixedPosition(pageNumber, 0, 0, 50)
时,文本最终出现在左上角,再次翻转。如果我分别使用源 PdfDocument 页面大小的宽度和高度作为左侧和底部位置的参数,它甚至不会到达右下角。

我可能做错了什么或误解了什么。不管怎样,这是我正在使用的代码:

private static int copyPdfPages(PdfDocument source, Document document, Integer start, Integer pages, Integer number) {
    int oldC;
    int max = start + pages - 1;
    Text text;
    for (oldC = start; oldC <= max; oldC++) {
        text = new Text(String.format("Page %d", number));
        PageSize pageSize = source.getDefaultPageSize();
        source.copyPagesTo(oldC, oldC, document.getPdfDocument());
        document.add(new Paragraph(text).setBorder(new SolidBorder(ColorConstants.RED, 1))
                .setFixedPosition(number++, pageSize.getWidth() - 55, pageSize.getHeight() - 30, 50));
    }
    return oldC - start;
}

public static void main(String[] args) throws IOException {
    String path = "/path/to/target";

    FileOutputStream fos = new FileOutputStream(path);
    PdfDocument pdfDocTgt = new PdfDocument(new PdfWriter(fos));
    Document document = new Document(pdfDocTgt);

    PdfDocument pdfDocSrc = new PdfDocument(new PdfReader(new FileInputStream("path/to/source")));

    copyPdfPages(pdfDocSrc, document, 1, pdfDocSrc.getNumberOfPages(), 1);

    pdfDocTgt.close();
    pdfDocSrc.close();
    document.flush();
    document.flush();
    fos.flush();
    fos.close();
}

这是 pdf 源:https://drive.google.com/open?id=11_9ptuoRqS91hI3fDcs2FRsIUEiX0a84

请帮忙(对我的英语感到抱歉)。

pdf copy itext7
2个回答
5
投票

问题

问题是

Document.add
假设当前页面的当前内容中的指令在其末尾将图形状态基本上恢复到其初始状态(或者期望差异对输出的影响)。

在您的示例 PDF 中,不满足此假设,特别是页面内容说明以

开头
0.750000 0.000000 0.000000 -0.750000 0.000000 841.920044 cm

将当前变换矩阵更改为

  • 将所有内容缩小至 75% 并且
  • 垂直翻转坐标系。

前一个更改导致您添加的内容不在页面角落,而是在更靠近中心的位置;后者导致它垂直镜像,并且更多地镜像到底部而不是页面顶部。

修复

如果不知道页面的当前内容最后是否具有本质上恢复的图形状态(通常是处理页面内容而不是自己生成的情况),则应避免通过添加内容Document实例,而是使用由构造函数生成的

PdfCanvas
,该构造函数将当前页面内容包装在保存图形状态...恢复图形状态信封中。

例如对于您的任务:

private static int copyPdfPagesFixed(PdfDocument source, PdfDocument target, int start, int pages, int number) { int oldC; int max = start + pages - 1; Text text; for (oldC = start; oldC <= max; oldC++) { text = new Text(String.format("Page %d", number)); source.copyPagesTo(oldC, oldC, target); PdfPage newPage = target.getLastPage(); Rectangle pageSize = newPage.getCropBox(); try ( Canvas canvas = new Canvas(new PdfCanvas(newPage, true), target, pageSize) ) { canvas.add(new Paragraph(text).setBorder(new SolidBorder(ColorConstants.RED, 1)) .setFixedPosition(number++, pageSize.getWidth() - 55, pageSize.getHeight() - 30, 50)); } } return oldC - start; }

AddPagenumberToCopy方法) 上面使用的

PdfCanvas

构造函数记录为

/**
 * Convenience method for fast PdfCanvas creation by a certain page.
 *
 * @param page           page to create canvas from.
 * @param wrapOldContent true to wrap all old content streams into q/Q operators so that the state of old
 *                       content streams would not affect the new one
 */
public PdfCanvas(PdfPage page, boolean wrapOldContent)

这样使用

try ( PdfDocument pdfDocSrc = new PdfDocument(new PdfReader(SOURCE)); PdfDocument pdfDocTgt = new PdfDocument(new PdfWriter(TARGET)) ) { copyPdfPagesFixed(pdfDocSrc, pdfDocTgt, 1, pdfDocSrc.getNumberOfPages(), 1); }

添加页码到复制测试testLikeAibanezFixed


第一个结果页面的顶部如下所示:


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.