首页 文章

使用iTextSharp生成的PDF始终会提示在关闭时保存更改 . 使用非Acrobat PDF阅读器查看时页面丢失

提问于
浏览
0

我最近使用iTextSharp通过从现有PDF导入20个页面然后将动态生成的链接添加到最后一页的底部来创建PDF . 它很好......有点儿 . 在Windows PC上在Acrobat Reader中查看生成的PDF会按预期显示所有内容,但在关闭文档时它始终会询问“您是否要保存更改?” . 使用PDF Reader在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等上缺少页面的问题,但是如果你知道其他什么可能导致我想听到它 .

任何建议都会非常受欢迎!谢谢!

1 回答

  • 3

    乍一看(并且还没有多少咖啡)看起来你在三个不同的上下文中使用 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();
            }
        }
    }
    

相关问题