根据此处评论中的建议,我重构了我的方法以尝试将数据分配给 iTextSharp.text.Document “使用”之外的 MemoryStream(但在 MemoryStream using 子句中):
internal static HttpResponseMessage GeneratePDFOfReportFutures()
{
HttpResponseMessage result = null;
futureReports = GetAllFutureReports();
try
{
using (var ms = new MemoryStream())
{
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25)) // the "Rotate" makes it landscape orientation
{
using (PdfWriter.GetInstance(doc, ms))
{
doc.Open();
. . .
// "int i" is for testing a quick exit of this long-running loop
int i = 0;
foreach (QueuedReports qr in futureReports)
{
var tblRow = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 4f
};
float[] tblRowWidths = new float[] { 220f, 180f, 220f, 160f, 160f, 340f };
tblRow.SetWidths(tblRowWidths);
tblRow.HorizontalAlignment = Element.ALIGN_LEFT;
var phraseRptName = new Phrase(qr.ReportName, helvetica9);
var cellRptName = GetCellForBorderedTable(phraseRptName, Element.ALIGN_CENTER, BaseColor.WHITE);
cellRptName.VerticalAlignment = Element.ALIGN_MIDDLE;
tblRow.AddCell(cellRptName);
. . .
tblRow.AddCell(cellRecipients);
doc.Add(tblRow);
i++;
if (i >= 12)
{
break;
}
} // foreach
} // pdfWriter
} // doc
var bytes = ms.ToArray();
result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(bytes)
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = string.Format("{0}.pdf", "test")
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
} // memoryStream
} // try
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return result;
} // GeneratePDFOfReportFutures
使用“break”行中的断点,我执行 (F10) 并在到达字节分配之前捕获以下异常:
System.ObjectDisposedException 被捕获 HResult=-2146232798
Message= Cannot access a closed Stream。Source=mscorlib
ObjectName="" StackTrace:在 System.IO.__Error.StreamIsClosed() 在 System.IO。MemoryStream .Write(Byte[] buffer, Int32 offset, Int32 count) at iTextSharp.text.pdf.OutputStreamCounter.Write(Byte[] buffer, Int32 offset, Int32 count) at iTextSharp.text.pdf.PdfIndirectObject.WriteTo(Stream os ) 在 iTextSharp.text.pdf。PdfWriteriTextSharp.text.pdf.PdfWriter.PdfBody.Add(PdfObject objecta, Int32 refNumber, Int32 generation, Boolean inObjStm) 在 iTextSharp.text.pdf.PdfWriter.PdfBody 的 .PdfBody.Write(PdfIndirectObject 间接,Int32 refNumber,Int32 生成)。 Add(PdfObject objecta, PdfIndirectReference refa, Boolean inObjStm) at iTextSharp.text.pdf.PdfWriter.PdfBody.Add(PdfObject objecta, PdfIndirectReference refa) at iTextSharp.text.pdf.PdfWriter.AddToBody(PdfObject objecta, PdfIndirectReference refa) at iTextSharp。 text.pdf.Type1Font.WriteFont(PdfWriter writer, PdfIndirectReference piref, Object[] parms) at iTextSharp.text.pdf.FontDetails.WriteFont(PdfWriter writer) at iTextSharp.text.pdf.PdfWriter.AddSharedObjectsToBody() at iTextSharp.text。 iTextSharp.text 处的 pdf.PdfWriter.Close()。DocWriter.Dispose()
由于访问 PdfWriter 和/或 Doc 似乎是导致问题的原因,看来我不仅需要在 doc 使用中移动编写代码,还需要在 pdfWriter 使用中移动,所以我这样做了,像这样移动代码:
. . .
} // foreach
var bytes = ms.ToArray();
result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(bytes)
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = string.Format("{0}.pdf", "test")
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
} // pdfWriter
} // doc
} // memoryStream
} // try
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return result;
...但我仍然得到完全相同的例外。但是,我现在看到的内容与上一篇文章中描述的内容之间存在差异,因为直到 I F10 在此行上才会引发异常:
} // pdfWriter
如果我将返回线移到上方(并且仍然保持在 catch 块下方),如下所示:
return result;
} // pdfWriter
...在“返回结果”行的 F10ing 上引发异常。
为什么会失败,我该如何预防?