【问题标题】:PDF generated with iTextSharp always prompts to save changes when closing. And has missing pages when viewed with non-Acrobat PDF readers使用 iTextSharp 生成的 PDF 在关闭时总是提示保存更改。使用非 Acrobat PDF 阅读器查看时缺少页面
【发布时间】:2015-09-13 21:54:18
【问题描述】:

我最近使用 iTextSharp 创建 PDF,方法是从现有 PDF 导入 20 页,然后将动态生成的链接添加到最后一页的底部。它工作正常......有点。在 Windows PC 上的 Acrobat Reader 中查看生成的 PDF 会按预期显示所有内容,尽管在关闭文档时它总是询问“您要保存更改吗?”。在带有 PDF 阅读器的 Surface Pro 上查看生成的 PDF 会显示没有第一页和最后一页的文档。显然,在使用 Polaris Office 的移动设备上,第一页和最后一页也丢失了。

我想知道在生成新 PDF 时是否没有完全正确地关闭它,这就是它询问“您要保存更改吗?”的原因。关闭它时。也许这也是它在某些 PDF 阅读器应用程序中无法正确显示的原因。

代码如下:

    using (var reader = new PdfReader(HostingEnvironment.MapPath("~/app/pdf/OriginalDoc.pdf")))
    {


        using (
            var fileStream =
                new FileStream(
                    HostingEnvironment.MapPath("~/documents/attachments/DocWithLink_" + id + ".pdf"),
                    FileMode.Create, FileAccess.Write))
        {
            var document = new Document(reader.GetPageSizeWithRotation(1));
            var writer = PdfWriter.GetInstance(document, fileStream);

            using (PdfStamper stamper = new PdfStamper(reader, fileStream))
            {
                var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252,
                    BaseFont.NOT_EMBEDDED);
                Font linkFont = FontFactory.GetFont("Arial", 12, Font.UNDERLINE, BaseColor.BLUE);
                document.Open();

                for (var i = 1; i <= reader.NumberOfPages; i++)
                {
                    document.NewPage();

                    var importedPage = writer.GetImportedPage(reader, i);
                    // Copy page of original document to new document.

                    var contentByte = writer.DirectContent;
                    contentByte.AddTemplate(importedPage, 0, 0);

                    if (i == reader.NumberOfPages) // It's the last page so add link.
                    {
                        PdfContentByte cb = stamper.GetOverContent(i);

                        //Create a ColumnText object
                        var ct = new ColumnText(cb);
                        //Set the rectangle to write to
                        ct.SetSimpleColumn(100, 30, 500, 90, 0, PdfContentByte.ALIGN_LEFT);

                        //Add some text and make it blue so that it looks like a hyperlink
                        var c = new Chunk("Click here!", linkFont);

                        var congrats = new Paragraph("Congratulations on reading the eBook!    ");
                        congrats.Alignment = PdfContentByte.ALIGN_LEFT;

                        c.SetAnchor("http://www.domain.com/pdf/response/" + encryptedId);
                        //Add the chunk to the ColumnText
                        congrats.Add(c);
                        ct.AddElement(congrats);

                        //Tell the system to process the above commands
                        ct.Go();
                    }
                }
            }
        }
    }

我查看了这些具有类似问题的帖子,但似乎都没有提供我需要的答案: iTextSharp-generated PDFs cause save dialog when closing
Using iTextSharp to write data to PDF works great, but Acrobat Reader asks 'Do you want to save changes' when closing file (或者他们指的是内存流而不是写入磁盘等)

我的问题是,如何修改上述内容,以便在 Acrobat Reader 中关闭生成的 PDF 时没有“您要保存更改吗?”迅速的。该问题的答案可能会解决 Surface Pro 等缺少页面的问题,但如果您知道其他可能导致的问题,我想听听。

非常欢迎任何建议!谢谢!

【问题讨论】:

  • 请分享一个示例结果 PDF。

标签: c# pdf pdf-generation itextsharp


【解决方案1】:

乍一看(还没有多少咖啡),您似乎在三种不同的上下文中使用PdfReader,作为PdfStamper 的源,作为Document 的源和作为源用于导入。因此,您实际上是在将一个您也在写入的文档导入到自身中。

为了让您快速了解一下,下面的代码实质上会将source.pdf 的内容克隆到dest.pdf

using (var reader = new PdfReader("source.pdf")){
    using (var fileStream = new FileStream("dest.pdf", FileMode.Create, FileAccess.Write)){
        using (PdfStamper stamper = new PdfStamper(reader, fileStream)){
        }
    }
}

因为它会为您完成所有克隆,所以您不需要导入页面或任何东西。

然后,如果您只想在最后一页添加一些文本,您可以使用上面的方法并使用GetOverContent()PdfStamper 询问PdfContentByte,并告诉它什么页码你有兴趣。然后你就可以使用你的 ColumnText 逻辑的其余部分了。

using (var reader = new PdfReader("Source.Pdf")) {
    using (var fileStream = new FileStream("Dest.Pdf"), FileMode.Create, FileAccess.Write) {
        using (PdfStamper stamper = new PdfStamper(reader, fileStream)) {

            //Get a PdfContentByte object
            var cb = stamper.GetOverContent(reader.NumberOfPages);

            //Create a ColumnText object
            var ct = new ColumnText(cb);
            //Set the rectangle to write to
            ct.SetSimpleColumn(100, 30, 500, 90, 0, PdfContentByte.ALIGN_LEFT);

            //Add some text and make it blue so that it looks like a hyperlink
            var c = new Chunk("Click here!", linkFont);

            var congrats = new Paragraph("Congratulations on reading the eBook!    ");
            congrats.Alignment = PdfContentByte.ALIGN_LEFT;

            c.SetAnchor("http://www.domain.com/pdf/response/" + encryptedId);
            //Add the chunk to the ColumnText
            congrats.Add(c);
            ct.AddElement(congrats);

            //Tell the system to process the above commands
            ct.Go();
        }
    }
}

【讨论】:

  • 完美信息感谢克里斯!我不知道 PdfStamper 克隆了整个文档,这就是我的问题。
猜你喜欢
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
相关资源
最近更新 更多