iText7 Java添加文本问题

用户名

我正在使用iText 7复制pdf页面并为这些页面编号。因此,我不需要手动编号。但是生成的pdf文件中的数字存在问题。看起来是这样的:

发行图片

而且我已经考虑了许多小时,仍然无法弄清楚。

我的代码:

import com.itextpdf.io.font.FontConstants;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;

import java.io.File;
import java.io.IOException;

public class NumberingInJava {

public static final String SRC = "D:/temp/num_src.pdf";
public static final String DEST = "D:/temp/edited_numbering.pdf";

public static final String[] NUM4SAMPLE = {"02A", "03A", "03B", "03C", "04A", "08A"};

public static final double XCOOR = 230;
public static final double YCOOR = 795;//755

public static void main(String[] args) throws IOException {
    File file = new File(DEST);
    file.getParentFile().mkdirs();
    new NumberingInJava().manipulatePdf(SRC, DEST, NUM4SAMPLE);
}

private void manipulatePdf(String src, String dest, String[] numbering4what) throws IOException {

    //Initialize PDF document
    PdfDocument pdfDocToRead = new PdfDocument(new PdfReader(src));
    PdfDocument pdfDocToWrite = new PdfDocument(new PdfWriter(dest));

    for(String s : numbering4what) {
        println(s);
    }

    String number = null;
    PdfPage tempPage = null;
    for (int i=0; i<numbering4what.length; i++) {
        pdfDocToRead.copyPagesTo(1, 2, pdfDocToWrite);
        number = numbering4what[i];
        println(number);
        tempPage = pdfDocToWrite.getPage(2*(i+1)-1);

        numberingPage(tempPage, number);

        println("pdfDocToWrite.numberOfPages : "+pdfDocToWrite.getNumberOfPages());
    }

    pdfDocToRead.close();
    pdfDocToWrite.close();

    println("\nNumber added!");
}

private void numberingPage(PdfPage pdfPage, String number) throws IOException {
    println(pdfPage);
    PdfCanvas canvas = new PdfCanvas(pdfPage);
    canvas.beginText().setFontAndSize(PdfFontFactory.createFont(FontConstants.HELVETICA), 22)
            .moveText(XCOOR, YCOOR)
            .showText(number)
            .endText();

    println("number: "+number);

}

private void println(Object obj) {
    System.out.println(obj);
}
}

控制台输出:

02A 
03A 
03B 
03C 03A 
04A 
08A 
02A 
com.itextpdf.kernel.pdf.PdfPage@cf768c 
17:58:07,457 | -ch.qos.logback.classic.LoggerContext中的-INFO [默认]-找不到资源[logback.groovy] 
17 ch.qos.logback.classic.LoggerContext中的:58:07,458 | -INFO [默认]-ch.qos.logback.classic.LoggerContext中找不到资源[logback-test.xml] 
17:58:07,458 | -INFO [默认]-在[jar:file:/ D:/Java_Packages/ext_lib/iText/itext7-7.0.1/itext7-itext-rups-7.0.1.jar!/logback.xml]中找到资源[logback.xml] 
17:58:07,459 | -WARN在ch.qos.logback.classic.LoggerContext中[默认]-资源[logback.xml]在类路径上多次出现。
17:58:07,459 | -ch.qos.logback.classic.LoggerContext中的[默认]-资源[logback.xml]出现在[jar:file:/ D:/Java_Packages/ext_lib/iText/itext7-7.0.1 /itext7-itext-rups-7.0.1-jar-with-dependencies.jar!/logback.xml] 
17:58:07,459 | -ch.qos.logback.classic.LoggerContext中的WARN [默认]-资源[logback。 xml]发生在[jar:file:/ D:/Java_Packages/ext_lib/iText/itext7-7.0.1/itext7-itext-rups-7.0.1-sources.jar!/logback.xml] 
17:58:07,459 | ch.qos.logback.classic.LoggerContext中的-WARN [默认]-资源[logback.xml]出现在[jar:file:/ D:/Java_Packages/ext_lib/iText/itext7-7.0.1/itext7-itext-rups -7.0.1.jar!/logback.xml]
ch.qos.logback.core.joran.spi.ConfigurationWatchList@8080bb中的17:58:07,501 | -INFO-URL [jar:file:/ D:/Java_Packages/ext_lib/iText/itext7-7.0.1/itext7-itext ch.qos.logback.core.joran.action.AppenderAction中的-rups-7.0.1.jar!/logback.xml]不是文件类型
17:58:07,662 | -INFO在ch.qos.logback.classic.joran.action.ConfigurationAction中-未设置调试属性
17:58:07,829 | -INFO .itextpdf.rups.view.DebugAppender] 
17:58:07,851 | -INFO在ch.qos.logback.core.joran.action.AppenderAction中-将追加程序命名为[DEFAULT_APP] 
17:58:07,940 | -INFO在ch.qos中.logback.core.joran.action.NestedComplexPropertyIA-假设[encoder]属性的默认类型为[ch.qos.logback.classic.encoder.PatternLayoutEncoder]属性
17:58:08,045 | -INFO在ch.qos.logback.core.joran中.action.AppenderAction-关于实例化类型为[com.itextpdf.rups.view.StyleAppender]的附加程序 
17:58:08,046 | -ch.qos.logback.core.joran.action.AppenderAction中的-INFO-将追加程序命名为[INFO_APP] 
17:58:08,062 | -INFO在ch.qos.logback.core.joran.action.NestedComplexPropertyIA中-假设[encoder]属性的默认类型为[ch.qos.logback.classic.encoder.PatternLayoutEncoder]
ch.qos.logback.core.joran.action.AppenderAction中的17:58:08,063 | -INFO |即将实例化[com.itextpdf.rups.view.DebugAppender]类型的附加程序
17:58:08,063 | -ch中的-INFO .qos.logback.core.joran.action.AppenderAction-在ch.qos.logback.core.joran.action.NestedComplexPropertyIA中将附加程序命名为[DEBUG_APP] 
17:58:08,065 | -INFO-假定默认类型为[ch.qos。用于[encoder]属性的logback.classic.encoder.PatternLayoutEncoder]  
17:58:08,066 | -INFO在ch.qos.logback.core.joran.action.AppenderAction中-关于实例化类型[com.itextpdf.rups.view.DebugAppender]的附加程序
17:58:08,066 | -ch.qos.logback.core.joran.action.AppenderAction中的-INFO-将追加程序命名为[TRACE_APP] 
17:58:08,067 | -INFO在ch.qos.logback.core.joran.action.NestedComplexPropertyIA中-假设[encoder]属性的默认类型为[ch.qos.logback.classic.encoder.PatternLayoutEncoder] 
17:58:08,069 | -INFO在ch.qos.logback.core.joran.action中。 AppenderAction-要实例化[com.itextpdf.rups.view.StyleAppender]类型的追加程序
17:58:08,069 | -ch.qos.logback.core.joran.action.AppenderAction中的-INFO-将追加程序命名为[IMPORTANT_APP] 
17: ch.qos.logback.core.joran.action.NestedComplexPropertyIA中的58:08,075 | -INFO |假设[encoder]属性的默认类型为[ch.qos.logback.classic.encoder.PatternLayoutEncoder] 
17:58:08,076 | -INFO在ch.qos.logback.classic.joran.action.LoggerAction中-将记录器[com.itextpdf]的可加性设置为false
ch.qos.logback.core.joran.action.AppenderRefAction中的17:58:08,077 | -INFO-将名为[IMPORTANT_APP]的附加程序附加到Logger [com.itextpdf]
ch.qos.logback.classic.joran.action.ConfigurationAction中的 17:58:08,078 | -INFO中-配置结束。 
17 :58:08,078 | -ch.qos.logback.core.joran.action.AppenderRefAction中的INFO-将名为[INFO_APP]的附加程序附加到Logger [com.itextpdf]
ch.qos.logback.core.joran.action.AppenderRefAction中的17:58:08,078 | -INFO |将名为[DEBUG_APP]的附加程序附加到Logger [com.itextpdf] 
17:58:08,078 | -INFO中ch.qos.logback .core.joran.action.AppenderRefAction-将名为[TRACE_APP]的附加程序附加到Logger [com.itextpdf] 
17:58:08,078 | -ch.qos.logback.classic.joran.action.RootLoggerAction中的-INFO-设置ROOT记录器的级别到TRACE 
17:58:08,078 | -ch.qos.logback.core.joran.action.AppenderRefAction中的信息-将名为[DEFAULT_APP]的附加程序附加到Logger [ROOT] 
17:58:08,082 | ch.qos.logback中的-INFO .classic.joran.JoranConfigurator @ 1c24521-将当前配置注册为安全的回退点

数:02A pdfDocToWrite.numberOfPages:2 03A com.itextpdf.kernel.pdf.PdfPage@11aa95a 号:03A pdfDocToWrite.numberOfPages:4 03B com.itextpdf.kernel.pdf.PdfPage@bc05a6 数:03B pdfDocToWrite.numberOfPages:6 03C COM .itextpdf.kernel.pdf.PdfPage @ ef309d 数:03C pdfDocToWrite.numberOfPages:8 04A com.itextpdf.kernel.pdf.PdfPage@1fc609f 数:04A pdfDocToWrite.numberOfPages:10 08A com.itextpdf.kernel.pdf.PdfPage@173813a 编号:08A pdfDocToWrite.numberOfPages:12

已添加号码!

流程结束,退出代码为0

编辑:我已经在Dropbox上上传了一个模拟文档和一个已编辑文档,这里是:模拟文档

编辑的模拟文档

mkl

原因

该问题是由于iText试图使结果PDF变小而引起的:

当您将pdfDocToRead多个页面复制到时pdfDocToWrite,实际的页面内容流,页面资源等仅被复制一次,对于每个副本和页面,仅生成一个引用这些数据的小对象一次。

这种优化还不是问题,但进一步的微观优化是,

PdfCanvas canvas = new PdfCanvas(pdfPage);

PdfCanvas帮助程序方法用于检索将添加内容的内容流:

private static PdfStream getPageStream(PdfPage page) {
    PdfStream stream = page.getContentStream(page.getContentStreamCount() - 1);
    return stream == null || stream.getOutputStream() == null || stream.containsKey(PdfName.Filter) ? page.newContentStreamAfter() : stream;
}

如您所见,通常会在页面(page.newContentStreamAfter())中添加新的内容流仅当已经有内容流并且该流没有过滤器(例如用于压缩)时,才使用此现有内容流向其追加数据。

对于您的文档,不会压缩为每个源页面复制的单个内容流。因此,这两个优化导致您的所有PdfCanvas canvas实例附加到同一单个内容流。

解决方法

显而易见的解决方法是规避后者的优化:替换行

PdfCanvas canvas = new PdfCanvas(pdfPage);

经过

PdfCanvas canvas = new PdfCanvas(pdfPage.newContentStreamAfter(), pdfPage.getResources(), pdfPage.getDocument());

(在StampPageNumbers.java方法中numberingPage

本质上,如果原始内容流被压缩,也将发生这种情况。

(通常,实际上可能必须先在当前内容之前使用save-graphics-state指令添加一个新的内容流,并在当前内容之后最初向新的内容流添加一个restore-graphics-state指令;对于您的示例文档,但是,这不是必需的,因为当前状态不会不利地改变图形状态。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在iText7中的jar中提供字体

来自分类Dev

iText 7添加彩色文本并填充到矩形

来自分类Dev

IText7和C#中缺少GetPageN方法

来自分类Dev

iText7以错误的顺序读出行

来自分类Dev

iText7:如何获取段落的实际宽度

来自分类Dev

在iText7(.NET)中将页脚添加到现有PDF的每一页

来自分类Dev

iText7(.net)SignExternalSignatureContainer NullReferenceException

来自分类Dev

如何使用itext7从标记的pdf中的结构元素中提取文本

来自分类Dev

使用itext7的addind文本

来自分类Dev

我如何使用itext7从存储在Blob存储中的pdf中提取文本?

来自分类Dev

用iText7填充pdf检查字段

来自分类Dev

什么可以替代itext7中的短语?

来自分类Dev

iText7数字签名图像对齐

来自分类Dev

iText 7添加彩色文本并填充到矩形

来自分类Dev

在IText7中创建PdfFont

来自分类Dev

itext 7表边框问题

来自分类Dev

在带有iText7的页面上移动文本,保留字体,颜色,样式等,但更改文本的大小

来自分类Dev

itext7 中可以避免添加 xmp:ModifyDate 吗?

来自分类Dev

使用 IText7 将 SVG 图像添加到 PDF

来自分类Dev

如何使用带有 C# 的 itext7 将 u3d 添加到现有的 pdf 中

来自分类Dev

iText7 - 如何设置 LoggerFactory?

来自分类Dev

itext7 java.lang.NoClassDefFoundError: org.bouncycastle.asn1.esf.SignaturePolicyIdentifier

来自分类Dev

iText7 - 在表格问题中显示文本

来自分类Dev

在itext7中,如何按添加时间更改附件显示顺序

来自分类Dev

iText7 无法设置日志

来自分类Dev

iText7 目录

来自分类Dev

Itext7 pdf.version.not.valid

来自分类Dev

iText7 setRotation() 无法正常工作

来自分类Dev

iText7 图像透明度