使用 itext 生成的 PDF 会“损坏”;使用 SetSimpleColumn() 时

发布于 2024-12-17 10:30:35 字数 1784 浏览 1 评论 0原文


首先我想指出stackowerflow过去帮助我解决了很多问题,所以谢谢大家。但现在我遇到了一个我还没有找到解决方案的问题,这让我发疯。我的母语不是英语,因此对任何语言错误表示歉意。

所以这里是:

我正在使用 itextsharp 库(顺便说一句,这是一个很棒的库)生成 pdf。我从某种 pdf 表单/模板开始,向其中添加“填写”数据。我正在使用 PdfReader 读取模板 pdf,并通过为各个页面调用 PdfStamper 方法 GetOverContent(pageNum) 我得到 PdfContentByte.通过该 PdfContentByte,我添加了我的文本/数据(BeginTextEndText 在每个页面上使用)。大部分文本都是我使用 ShowTextAligned 方法添加的。一切正常,生成的 pdf 包含我的文本。问题开始于我必须添加“分栏”文本。我使用以下代码执行此操作:

ColumnText ct = new ColumnText(cb);//cb is PdfContentByte
Phrase p = new Phrase(txt, FontFactory.GetFont(DEFAULT_FONT, BaseFont.CP1250, true, font_size));
ct.SetSimpleColumn(p, x, y, x+width, y+height, 10, alignment);
ct.Go();
setDefaultFont();//sets font to PdfContentByte again with setFontAndSize and SetColorFill

使用此代码添加分栏文本 OK,但在此之后使用 ShowTextAligned 添加的文本(在同一页面/同一 PdfContentByte 上)不可见在 Acrobat Reader 中。

这是“有趣”的部分 - 用福昕阅读器打开的同一个 pdf 文件中的文本很好/可见/正常。

因此,添加 ColumnText 后使用 ShowTextAligned 添加的文本在 acrobat reader 中不可见,但在 Foxit reader 中可见。此问题存在于一个页面内,新页面会重置此问题(下一页的 PdfContentByte 是新的)。

我的解决方法是在所有 ShowTextAligned 调用之后添加所有 ColumnText。直到今天,当客户使用 acrobat reader 打印生成的 pdf 时,该方法一直有效,在打印文档后,显示 pdf 包含错误并应联系 pdf 作者的消息。 Adobe Reader 版本为 10.1.1。问题不在客户计算机上,同样的情况也发生在我的计算机上。

在研究了网络之后,我安装了 Adob​​e Acrodat Pro Trial,其中包含工具 Preflight,该工具用于分析 pdf(据我所知)。该工具输出警告“操作员的内容状态流无效”。我被困在这里了。我相信添加的 ColumnText 内部存在问题,因为没有它们生成的文档不会导致显示/打印出现问题,并且预检状态“未发现问题”。

我可能遗漏了一些事实,问题出在我的代码中......

请帮助我,因为我已经没有想法了。 我希望这篇文章有一天能帮助其他遇到同样问题的人。 我无法附加示例 pdf,因为它包含敏感数据,但如果没有其他方法,我将重新创建场景/代码。

First I would like to point out that stackowerflow helped me with many problems in the past, so thank you all. But now I have come to problem that I haven't fount a solution for yet and it's driving me crazy. I'm not native english speaker, so sorry for any language mistakes.

So here it is:

I'm generating pdf with itextsharp library(great library by the way). I'm starting with some kind of pdf form/template, to which i'm adding 'fill-out' data. I'm using PdfReader to read template pdf and by caling PdfStamper method GetOverContent(pageNum) for individual pages I get PdfContentByte. With that PdfContentByte I'm adding my text/data (BeginText and EndText is used on every page). Most of text I add with method ShowTextAligned. That all ok, generated pdf contains my text. The problem begins where i have to add 'columned' text. I do that with following code:

ColumnText ct = new ColumnText(cb);//cb is PdfContentByte
Phrase p = new Phrase(txt, FontFactory.GetFont(DEFAULT_FONT, BaseFont.CP1250, true, font_size));
ct.SetSimpleColumn(p, x, y, x+width, y+height, 10, alignment);
ct.Go();
setDefaultFont();//sets font to PdfContentByte again with setFontAndSize and SetColorFill

Columned text is added with this code OK, but the text(on that same page/same PdfContentByte) added AFTER this with ShowTextAligned is not visible in Acrobat Reader.

Here is the 'fun' part - that text in same pdf file opened with foxit reader is fine/visible/ok.

So text added with ShowTextAligned after adding ColumnText is not visible in acrobat reader but visible in foxit reader just fine. This problem exists inside one page, new page resets this problem (PdfContentByte for next page is new).

My workaround for that was to add all ColumnText AFTER all calls of ShowTextAligned. That worked till today, when customer printed out generated pdf with acrobat reader, which after printing the document, displayed message that pdf contains error and that author of pdf should be contacted. Version of Adobe Reader is 10.1.1. Problem is not in customer computer, same thing hapens on my computer.

After researching the web I installed Adobe Acrodat Pro Trial which contains tool Preflight, which is purposed for analyzing pdfs (as far I understand). This tool outputs warning "Invalid content state stream for operator". And here I'm stucked. I belive the problem exists inside added ColumnText, because document generated without them causes no problem displaying/printing and Preflight states "No problem found".

It is possible that i'm missing some fact and that the problem is in my code...

Please help me, because i'm runnig out of ideas.
I hope this post will help someday someone else with the same problem.
I cannot attach sample pdf because it contains sensitive data, but if there is no other way, i'll recreate the scenario/code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心房的律动 2024-12-24 10:30:35

所以回答我的问题/问题:
使用 PdfContentByte 和方法 ShowTextAligned 写入 pdf 时,您必须在写入之前调用 BeginText,完成后必须调用 EndText。所以我做到了。但是,如果您想添加一些其他元素(例如 ColumnText、图像以及可能其他任何元素),则在调用 EndText 之前您无法执行此操作。如果这样做,生成的 pdf 将“有问题”/损坏。

因此,在伪代码中,以下是错误的:

BeginText();
ShowtextAligned();
AddImage();
ShowtextAligned();
EndText();

正确的用法是:

BeginText();
ShowtextAligned();
EndText();
AddImage();
BeginText();
ShowtextAligned();
EndText();

我希望这会帮助某人有一天在某个地方。

So to answer my question/problem:
When writing to pdf using PdfContentByte and using method ShowTextAligned you have to call BeginText before writing and after you are finished you have to call EndText. So i did. BUT if you want to add some other element(like ColumnText, Image and probably anything else) you can't do that before you call EndText. If you do, generated pdf will be 'problematical'/corrupted.

So in pseudocode following is wrong:

BeginText();
ShowtextAligned();
AddImage();
ShowtextAligned();
EndText();

Correct usage is:

BeginText();
ShowtextAligned();
EndText();
AddImage();
BeginText();
ShowtextAligned();
EndText();

I hope this will help someone someday somewhere.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文