关闭空iTextSharp文档时出错
本文关键字:出错 文档 iTextSharp | 更新日期: 2023-09-27 18:26:26
我正在成功合并PDF文档;现在,当我试图在没有选择PDF文档的情况下实现错误处理时,它在关闭文档时抛出一个错误:文档没有页面
如果"foreach"-循环中没有添加PDF文档,我仍然需要关闭该文档!?还是不?如果你打开一个对象,那么它一定会在某个时刻关闭。那么,在没有添加页面的情况下,如何正确地进行转义呢?
private void MergePDFs()
{
DataSourceSelectArguments args = new DataSourceSelectArguments();
DataView view = (DataView)SourceCertCockpit.Select(args);
System.Data.DataTable table = view.ToTable();
List<PdfReader> readerList = new List<PdfReader>();
iTextSharp.text.Document document = new iTextSharp.text.Document();
PdfCopy copy = new PdfCopy(document, Response.OutputStream);
document.Open();
int index = 0;
foreach (DataRow myRow in table.Rows)
{
if (ListadoCertificadosCockpit.Rows[index].Cells[14].Text == "0")
{
PdfReader Reader = new PdfReader(Convert.ToString(myRow[0]));
Chapter Chapter = new Chapter(Convert.ToString(Convert.ToInt32(myRow[1])), 0);
Chapter.NumberDepth = 0;
iTextSharp.text.Section Section = Chapter.AddSection(Convert.ToString(myRow[10]), 0);
Section.NumberDepth = 0;
iTextSharp.text.Section SubSection = Section.AddSection(Convert.ToString(myRow[7]), 0);
SubSection.NumberDepth = 0;
document.Add(Chapter);
readerList.Add(Reader);
for (int i = 1; i <= Reader.NumberOfPages; i++)
{
copy.AddPage(copy.GetImportedPage(Reader, i));
}
Reader.Close();
}
index++;
}
if (document.PageNumber == 0)
{
document.Close();
return;
}
document.Close();
string SalesID = SALESID.Text;
Response.ContentType = "application/pdf";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.AppendHeader("content-disposition", "attachment;filename=" + SalesID + ".pdf");
}
在过去,当您创建文档并"忘记"添加任何内容时,iText不会抛出异常。这就产生了一个只有一页空白的文档。这被认为是一个错误:人们不喜欢单页、空文档。因此,设计决定抛出一个异常。
对newPage()
进行了类似的操作。新页面可以显式触发(在代码中添加document.newPage()
时),也可以隐式触发(到达页面末尾时)。在过去,这经常导致不需要的空白页。因此,在当前页面为空的情况下,决定忽略newPage()
。
假设你有这个:
document.newPage();
document.newPage();
人们可能期望创建两个新页面。这不是真的。我们已经做出了忽略第二个document.newPage()
的设计决定,因为在第一个document.newPage()
之后没有添加任何内容。
这就引出了一个问题:如果我们想插入一个空白页怎么办?或者,在您的情况下:如果创建一个只有一页空白的文档是可以的,该怎么办?
在这种情况下,我们必须告诉iText当前页面不应被视为空页面。您可以通过引入以下行来做到这一点:
writer.setPageEmpty(false);
现在,当前页面会被愚弄,以为它有一些内容,即使它可能是空白的。
将这一行添加到代码中可以避免文档没有页面异常,并解决流未关闭的问题。
如果您想试用setPageEmpty()
方法,请查看NewPage示例。
您可以在关闭文档之前添加一个空页面,或者捕获异常并忽略它。
如果您仍然对某个解决方案感兴趣,或者可能是其他人。我遇到了完全相同的问题,我通过以下方式解决了问题:声明一个布尔值,以确定是否至少添加了一个页面,然后在关闭我引用的文档之前。如果没有复制任何页面,我会使用AddPages方法在文档中添加一个新页面,并使用矩形作为参数。我没有找到添加页面的最简单方法。
所以代码应该如下(可能有一些语法错误,因为我不熟悉C#):
private void MergePDFs()
{
DataSourceSelectArguments args = new DataSourceSelectArguments();
DataView view = (DataView)SourceCertCockpit.Select(args);
System.Data.DataTable table = view.ToTable();
List<PdfReader> readerList = new List<PdfReader>();
iTextSharp.text.Document document = new iTextSharp.text.Document();
PdfCopy copy = new PdfCopy(document, Response.OutputStream);
document.Open();
int index = 0;
foreach (DataRow myRow in table.Rows)
{
if (ListadoCertificadosCockpit.Rows[index].Cells[14].Text == "0")
{
PdfReader Reader = new PdfReader(Convert.ToString(myRow[0]));
Chapter Chapter = new Chapter(Convert.ToString(Convert.ToInt32(myRow[1])), 0);
Chapter.NumberDepth = 0;
iTextSharp.text.Section Section = Chapter.AddSection(Convert.ToString(myRow[10]), 0);
Section.NumberDepth = 0;
iTextSharp.text.Section SubSection = Section.AddSection(Convert.ToString(myRow[7]), 0);
SubSection.NumberDepth = 0;
document.Add(Chapter);
readerList.Add(Reader);
bool AtLeastOnePage = false;
for (int i = 1; i <= Reader.NumberOfPages; i++)
{
copy.AddPage(copy.GetImportedPage(Reader, i));
AtLeastOnePage = true;
}
Reader.Close();
}
index++;
}
if (AtLeastOnePage)
{
document.Close();
return true;
}
else
{
Rectangle rec = new Rectangle(10, 10, 10, 10);
copy.AddPage(rec, 1);
document.Close();
return false;
}
string SalesID = SALESID.Text;
Response.ContentType = "application/pdf";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.AppendHeader("content-disposition", "attachment;filename=" + SalesID + ".pdf");
}