c# - 尝试为所有 PDF 页面添加边框会引发 IO.Exception

标签 c# pdf itext

我有一个包含多个页面的现有 pdf 文件,我想为所有页面添加边框。

因此,我创建了一个从 PdfPageEventHelper 继承的类,并覆盖了 OnEndPage 并将该类的实例分配给 PdfWriter 实例的 PageEvent:

using iTextSharp.text;
using iTextSharp.text.pdf;

namespace My.Apps.WPF.Classes
{
    public class PdfEventHelper : PdfPageEventHelper
    {
        public override void OnEndPage(PdfWriter writer, iTextSharp.text.Document document)
        {
            // Add border to page
            PdfContentByte content = writer.DirectContent;
            iTextSharp.text.Rectangle rectangle = new iTextSharp.text.Rectangle(document.PageSize);
            rectangle.Left += document.LeftMargin;
            rectangle.Right -= document.RightMargin;
            rectangle.Top -= document.TopMargin;
            rectangle.Bottom += document.BottomMargin;
            content.SetColorStroke(BaseColor.BLACK);
            content.Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, rectangle.Height);
            content.Stroke();
        }
    }
}

然后在主程序中,我有一个方法可以在所有页面中返回一个带有边框的新PDF(源pdf文档'pdfFilePath'是横向的,所以我保持新的方向):
private string PutBorderToPdfPages(string pdfFilePath)
{
    string newPdf = @"C:\Output.pdf";

    using (var reader = new PdfReader(pdfFilePath))
    {
        using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
        {
            iTextSharp.text.Document document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
            PdfEventHelper pdfEvent = new PdfEventHelper();

            PdfWriter writer = PdfWriter.GetInstance(document, fileStream);
            writer.PageEvent = pdfEvent;

            document.Open();

            document.Close(); // here it crashes, see below in post exception thrown
            writer.Close();
        }
    }

    return newPdf;
}

在运行时,在线:
document.Close();

我得到一个 IO.Exception 说:

The document has no pages.



在这种情况下,Pdf 文档只有 1 页。

我究竟做错了什么?我不想在现有的 pdf 文件中写入任何内容,我只想创建一个与源完全相同但所有页面都有边框的新 PDF 文件。

更新 :

尝试#1 :

我已经在下面完成了,但是我把所有页面都变成了黑色(我不知道如何处理未填充的矩形):
private string PutBorderToPdfPages(string pdfFilePath)
{
    string newPdf = @"C:\Output.pdf";

    using (var reader = new PdfReader(pdfFilePath))
    {
        using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
        {
            using (var pdfStamper = new PdfStamper(reader, fileStream))
            {
                int PageCount = reader.NumberOfPages;   

                for (int p = 1; p <= PageCount; p++)
                {
                    // Add border to page                                
                    PdfContentByte cb = pdfStamper.GetOverContent(p);
                    iTextSharp.text.Rectangle rectangle = pdfReader.GetPageSizeWithRotation(p);
                    rectangle.BackgroundColor = iTextSharp.text.BaseColor.BLACK;                                
                    cb.Rectangle(rectangle);
                }                            
            }
        }
    }

    return newPdf;
}

尝试#2 :

在这次尝试中,我得到了一个 ObjectDisposedException:

Cannot access to a closed file.



退出使用 pdfStamper 时:
private string PutBorderToPdfPages(string pdfFilePath)
{
    string newPdf = @"C:\Output.pdf";

    using (var reader = new PdfReader(pdfFilePath))
    {
        using (var fileStream = new FileStream(newPdf, FileMode.Create, FileAccess.Write))
        {
                    iTextSharp.text.Document document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));                        
                    PdfWriter writer = PdfWriter.GetInstance(document, fileStream);

                    document.Open();

                    using (var pdfStamper = new PdfStamper(reader, fileStream))
                    {                            
                        for (int p = 0; p < pdfStamper.Reader.NumberOfPages; p++)                            
                        {
                            // Add border to page
                            PdfContentByte content = writer.DirectContent;
                            iTextSharp.text.Rectangle rectangle = new iTextSharp.text.Rectangle(document.PageSize);
                            rectangle.Left += document.LeftMargin;
                            rectangle.Right -= document.RightMargin;
                            rectangle.Top -= document.TopMargin;
                            rectangle.Bottom += document.BottomMargin;
                            content.SetColorStroke(iTextSharp.text.BaseColor.BLACK);
                            content.Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, rectangle.Height);
                            content.Stroke();
                        }
                        document.Close();
                        writer.Close();
                    }
        }
    }

    return newPdf;
}

最佳答案

你做

document.Open();

document.Close(); // here it crashes, see below in post exception thrown

IE。您开始一个新文档,不添加任何内容,然后关闭它。因此,iText 使用 The document has no pages. 响应的内容将为空。

因此,异常是完全正确的。

“现有pdf文件”的“为所有页面设置边框”的正确方法是
  • PdfReader 中打开文档,
  • 创建 PdfStamper操作 PdfReader ,
  • 遍历它的页面并添加边框,
  • 并关闭 PdfStamper .

  • 例如。像这样的源文件source和一个目标文件 dest :
    using (PdfReader reader = new PdfReader(source))
    using (PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create)))
    {
        for (int pageNumber = 1; pageNumber <= reader.NumberOfPages; pageNumber++)
        {
            Rectangle cropBox = reader.GetCropBox(pageNumber);
            Rectangle rectangle = new Rectangle(cropBox);
            rectangle.Left += 20;
            rectangle.Right -= 20;
            rectangle.Top -= 20;
            rectangle.Bottom += 20;
    
            PdfContentByte content = stamper.GetOverContent(pageNumber);
            content.SetColorStroke(iTextSharp.text.BaseColor.BLACK);
            content.Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, rectangle.Height);
            content.Stroke();
        }
    }
    

    关于c# - 尝试为所有 PDF 页面添加边框会引发 IO.Exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48148163/

    相关文章:

    c# - 加速像素格式转换 - BGR packed to RGB planar

    c# - 使用 MVVM 在 XAML 中禁用 TelerikGrid 中的行

    c# - 将文本文件加载到列表框中

    javascript - 在浏览器中将字节数组显示为 pdf 我尝试了堆栈溢出中的几个选项,但它对我不起作用

    c# - 从 itextsharp 注释弹出一个窗口显示图像和文本

    c# - Xamarin.Android 中的 Android 数据绑定(bind)库

    objective-c - 如何在 iPhone 上将二进制文件转换为 pdf 文件?

    ruby - 将元数据添加到 PDF

    java - 如何将过滤后的 jTable 的内容导出到 pdfpTable

    java - 使用 iText 5 生成 pdf 文件时出现问题