尝试在所有PDF页面上加边框会引发IO.Exception [英] Trying to put a border to all PDF pages throws an IO.Exception

查看:102
本文介绍了尝试在所有PDF页面上加边框会引发IO.Exception的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多页的pdf文件,我想在所有页面上加边框.

I have an existing pdf file with multiple pages to which I would like to put a border to all pages.

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

So I create a class that inherits from PdfPageEventHelper and I override the OnEndPage and assign the instance of that class to the PageEvent of PdfWriter instance:

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在其所有页面中都带有边框(源pdf文档'pdfFilePath'位于横向,因此我将方向保持在新的PDF中):

Then in main program I have a method that returns a new PDF with a border in all its pages (source pdf document 'pdfFilePath' is in landscape, so I keep orientation in new one):

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:

I get an IO.Exception that says:

该文档没有页面.

The document has no pages.

在这种情况下,Pdf文档只有一页.

In this case, Pdf document has only 1 page.

我做错了什么?我不想在现有的pdf文件中写任何东西,我只想创建一个与源完全相同的新PDF文件,但是在其所有页面中都带有边框.

What am I doing wrong? I do not want to write anything to the existing pdf file, I only want to create a new PDF file exactly the same as source but with a border in all its pages.

更新:

ATTEMPT#1 :

我已经完成以下操作,但是我将所有页面都显示为黑色(不知道如何填充未填充的矩形):

I have done below, but I get all page in black (I do not know how to do the rectangle not filled):

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;
}

ATTEMPT#2 :

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

In this attempt, I get an ObjectDisposedException:

无法访问已关闭的文件.

Cannot access to a closed file.

在退出使用pdfStamper时:

when exiting the using of 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

即您启动一个新文档,不添加任何内容,然后关闭它.因此,iText用The document has no pages.

I.e. you start a new document, add nothing to it, and then close it. Thus, it would be empty which iText responds to with The document has no pages.

因此,例外情况是完全正确的.

Thus, the exception is completely correct.

现有PDF文件" 中的在所有页面上加边框" 的正确方法是

  • PdfReader中打开文档,
  • 创建对该PdfReader进行操作的PdfStamper
  • 遍历页面并添加边框,
  • 并关闭PdfStamper.
  • open the document in a PdfReader,
  • create a PdfStamper operating on that PdfReader,
  • iterate over the pages of it and add borders,
  • and close the PdfStamper.

例如对于源文件source和目标文件dest:

E.g. like this for a source file source and a target file 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();
    }
}

这篇关于尝试在所有PDF页面上加边框会引发IO.Exception的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆