当我尝试使用iTextSharp构建包含多个表格的PDF文件时,收到以下错误消息:
无法访问已关闭的流。
下面是我的代码:
//Create a byte array that will eventually hold our final PDF
Byte[] bytes;
List<TableObject> myTables = getTables();
TableObject currentTable = new TableObject();
//Boilerplate iTextSharp setup here
//Create a stream that we can write to, in this case a MemoryStream
using (MemoryStream ms = new MemoryStream())
{
//Create an iTextSharp Document which is an abstraction of a PDF but **NOT** a PDF
using (Document doc = new Document(PageSize.A4, 10f, 10f, 10f, 0f))
{
foreach (TableObject to in myTables)
{
//Create a writer that's bound to our PDF abstraction and our stream
using (PdfWriter writer = PdfWriter.GetInstance(doc, ms))
{
if (!doc.IsOpen())
{
//Open the document for writing
doc.Open();
}
//Get the data from database corresponding to the current tableobject and fill all the stuff we need!
DataTable dt = getDTFromID(to._tableID);
Object[] genObjects = new Object[5];
genObjects = gen.generateTable(dt, currentTable._tableName, currentTable._tableID.ToString(), currentTable, true);
StringBuilder sb = (StringBuilder)genObjects[1];
String tableName = sb.ToString();
Table myGenTable = (Table)genObjects[0];
String table = genObjects[2].ToString();
using (StringReader srHtml = new StringReader(table))
{
//Parse the HTMLiTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml);
}
//should give empty page at the end, need to fix it later
doc.NewPage();
}
}
doc.Close();
}
//After all of the PDF "stuff" above is done and closed but **before** we
//close the MemoryStream, grab all of the active bytes from the stream
bytes = ms.ToArray();
}
//Now we just need to do something with those bytes.
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=Report_complete.pdf");
Response.BinaryWrite(bytes);
下面是我的www.example.com应用程序的完整堆栈跟踪asp.net:
[对象处理异常:无法访问已关闭的流。]
系统. IO.__错误.数据流关闭()+57
系统.IO.内存流.写入(字节[]缓冲区,Int 32偏移量,Int 32计数)+11011171 iTextSharp.文本.pdf.输出流计数器.写入(字节[]缓冲区,Int 32偏移量,Int 32计数)+52
翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:翻译:
(间接对象,整数32参考编号,整数32生成)+100
添加(PdfObject对象,Int 32引用编号,Int 32生成,对象中的布尔值)+385
添加到正文(PdfObject对象,PdfIndirectReference引用)+51
+317(数据写入器写入器,数据间接引用指针,对象[]参数)
+296,请输入您要的字体。
中文字幕翻译:中文字幕翻译:中文字幕翻译:中文字幕翻译:中文字幕翻译:中文字幕翻译:
联系我们联系方式+86
文件处理器()+10
+51系统. Web.UI.控件.OnLoad(事件参数e)+92
系统.Web.UI.控件.加载递归()+54
系统.Web.UI.页面.处理请求主页面(布尔值包括异步点之前的阶段,布尔值包括异步点之后的阶段)+772bytes
-Array应该可以在using语句中访问,但似乎存在错误。
我试过将foreach
循环移到using(writer ...)
块中:
//Create a byte array that will eventually hold our final PDF
//must be outside of the foreach loop (and everything else), because we store every single generated table in here for the final pdf!!
Byte[] bytes;
List<TableObject> myTables = getTables();
TableObject currentTable = new TableObject();
//Boilerplate iTextSharp setup here
//Create a stream that we can write to, in this case a MemoryStream
using (MemoryStream ms = new MemoryStream())
{
//Create an iTextSharp Document which is an abstraction of a PDF but **NOT** a PDF
using (Document doc = new Document(PageSize.A4, 10f, 10f, 10f, 0f))
{
//Create a writer that's bound to our PDF abstraction and our stream
using (PdfWriter writer = PdfWriter.GetInstance(doc, ms))
{
//loop all tableobjects inside the document & the instance of PDFWriter itself!
foreach (TableObject to in myTables)
{
//only happens on the first run!
if (!doc.IsOpen())
{
//Open the document for writing
doc.Open();
}
//Get the data from database corresponding to the current tableobject and fill all the stuff we need!
DataTable dt = getDTFromID(to._tableID);
Object[] genObjects = new Object[5];
genObjects = gen.generateTable(dt, currentTable._tableName, currentTable._tableID.ToString(), currentTable, true);
StringBuilder sb = (StringBuilder)genObjects[1];
String tableName = sb.ToString();
Table myGenTable = (Table)genObjects[0];
String table = genObjects[2].ToString();
using (StringReader srHtml = new StringReader(table))
{
//Parse the HTML
iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml);
}
//this will probably render a whole new page at the end of the file!! need to be fixed later!!!
doc.NewPage();
}
//After all of the PDF "stuff" above is done and closed but **before** we
//close the MemoryStream, grab all of the active bytes from the stream
bytes = ms.ToArray();
}
doc.Close();
}
}
//Now we just need to do something with those bytes.
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=ShiftReport_complete.pdf");
Response.BinaryWrite(bytes);
但我还是得到同样的错误。
6条答案
按热度按时间kpbpu0081#
默认情况下,PdfWriter关闭流。
vfhzx4xs2#
PdfWriter writer..
上的using
区块在尝试处置writer
时,可能会关闭基础数据流ms
。尝试使用不带
using
块的PdfWriter writer
进行删除,然后参阅。这样应该可以解决问题。laik7k3q3#
using命令会导致释放MemoryStream,因此在您访问它时,托管和非托管资源已经被释放。将以下代码放在foreach循环的右括号之后:
nbnkbykc4#
解决方案很简单,只需将
.ToList()
放入foreach
循环中的集合:this question下的This answer帮助我解决了这个问题。
rxztt3cl5#
当我有一个没有行的空表时,我用xmlworker(iTextSharp html到pdf)得到**“无法访问关闭的流”**:
dgenwo3n6#
此问题似乎是由于在关闭文档之前释放了PdfWriter所致。在PdfWriter的using语句内调用
doc.Close()
应该可以解决此问题。