使用itext 7将页码文本添加到pdf副本会被翻转/镜像 [英] Adding page number text to pdf copy gets flipped/mirrored with itext 7

查看:385
本文介绍了使用itext 7将页码文本添加到pdf副本会被翻转/镜像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以...我一直在尝试使用itext文档中提供的示例来合并文档并为合并结果创建TOC.但是,将页码文本添加到每个页面的部分无法正常工作.发生的情况是添加的文本在某个水平轴上翻转,如下图所示:

So... I've been trying to use the example provided in the documentation of itext for merging documents and creating a TOC for the merged result. But the part that adds page number text to every page isn't working as I would expect. What happens is that the text added gets flipped over some horizontal axis as shown in the next picture:

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

Also, the java doc for the method used to set a fixed position to the added text (public T setFixedPosition(int pageNumber, float left, float bottom, float width)) doesn't make sense to me:

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

Sets values for a absolute repositioning of the Element. The coordinates specified correspond to the bottom-left corner of the element and it grows upwards.

但是当我运行setFixedPosition(pageNumber, 0, 0, 50)时,文本结束于左上角,再次也翻转了.而且,如果我使用源PdfDocument页面大小中的宽度和高度分别作为左侧和底部位置的参数,那么它甚至都不会到达右下角.

But when I run setFixedPosition(pageNumber, 0, 0, 50) the text ends up in the upper left corner, again also flipped. And if I use the width and height from the page size of the source PdfDocument as parameters for left and bottom positions respectively it doesn't even reach bottom right corner.

我可能做错了什么或误解了.无论哪种方式,这都是我正在使用的代码:

I might be doing something wrong or misunderstanding something. Either way, here is the code I'm using:

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

请帮忙(对不起我的英语).

Help please (and sorry about my english).

推荐答案

问题

问题在于,Document.add假定当前页面的当前内容在其末尾处的指令将图形状态从本质上恢复为其初始状态(否则,期望差异对输出的影响)

The problem

The problem is that Document.add assumes that the instructions in the current content of the current page at its end have the graphics state essentially restored to its initial state (or else that the effects of the differences on the output are desired).

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

In your sample PDF this assumption is not satisfied, in particular the page content instructions start with

0.750000 0.000000 0.000000 -0.750000 0.000000 841.920044 cm

将当前转换矩阵更改为

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

以前的更改使您添加的内容不在页面角落,而是位于中心位置.后者导致它被垂直镜像,并更多地位于页面底部而不是页面顶部.

The former change causes your addition to not be in a page corner but instead instead somewhere more to the center; the latter causes it to be vertically mirrored and more to the bottom instead of to the top of the page.

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

If one does not know whether the current contents of the page have an essentially restored graphics state at the end (usually the case if one processes page contents one has not generated oneself), one should refrain from adding content via a Document instance but instead use a PdfCanvas generated with a constructor that wraps the current page content in a save-graphics-state ... restore-graphics-state envelop.

例如为您的任务:

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

(上面使用的PdfCanvas构造函数记录为

The PdfCanvas constructor used above is documented as

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

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

the top of the first result page looks like this:

这篇关于使用itext 7将页码文本添加到pdf副本会被翻转/镜像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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