【问题标题】:Adding page number text to pdf copy gets flipped/mirrored with itext 7将页码文本添加到 pdf 副本会被 itext 7 翻转/镜像
【发布时间】:2019-03-15 13:29:54
【问题描述】:

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

此外,用于为添加的文本 (public T setFixedPosition(int pageNumber, float left, float bottom, float width)) 设置固定位置的方法的 java 文档对我来说没有意义:

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

但是当我运行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


    【解决方案1】:

    问题

    问题在于Document.add 假定当前页面的当前内容中的指令在其末尾具有基本恢复到其初始状态的图形状态(或者需要差异对输出的影响) .

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

    开头
    0.750000 0.000000 0.000000 -0.750000 0.000000 841.920044 cm
    

    将当前变换矩阵更改为

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

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

    修复

    如果不知道页面的当前内容最后是否具有基本恢复的图形状态(通常是在处理页面内容的情况下而不是自己生成),应该避免通过 Document 实例添加内容,而是使用由构造函数生成的 PdfCanvas,该构造函数将当前页面内容包装在 save-graphics-state ... restore-graphics-state 信封中。

    例如为您的任务:

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

    (AddPagenumberToCopy 测试testLikeAibanezFixed)

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

    【讨论】:

    • 非常感谢!我会立即尝试并在需要时返回。
    • @aibanez 如果这充分回答了您的问题,请接受答案。
    • 感谢您为我节省了数小时的拉头发时间。
    猜你喜欢
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 2016-08-04
    • 2014-02-17
    • 2023-03-12
    • 2019-03-26
    • 2017-12-19
    • 2011-07-25
    相关资源
    最近更新 更多