PageEvent 抛出 Cannot access a closed Stream
PageEvent is throwing Cannot access a closed Stream
添加PageEvent生成Header和Footer时,关闭后好像在尝试写入stream。我不确定将页面事件放在哪里。如果我删除页面事件,它会生成 pdf 文件。
p.Parse(html);
是 "Cannot access a closed Stream" 失败的地方。删除 writer.PageEvent
将导致 Parse 工作,但它不会生成 header/footer.
我使用 this 页面作为 header/footer 代码的参考。
代码:
try {
using(var stream = new MemoryStream()) {
using(var document = new Document(PageSize.LETTER, 20 f, 20 f, 5 f, 5 f)) {
using(var writer = PdfWriter.GetInstance(document, stream)) {
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
writer.PageEvent = new HeaderFooter(Header, Footer); // if I remove this it generates fine but then I don't get a header/footer.
var tagProcessors = (DefaultTagProcessorFactory) Tags.GetHtmlTagProcessorFactory();
tagProcessors.RemoveProcessor(HTML.Tag.IMG); // remove the default processor
tagProcessors.AddProcessor(HTML.Tag.IMG, new CustomImageTagProcessor()); // use our new processor
htmlContext.SetTagFactory(tagProcessors);
ICSSResolver CssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
CssResolver.AddCss(Css, true);
IPipeline pipeline =
new CssResolverPipeline(CssResolver,
new HtmlPipeline(htmlContext,
new PdfWriterPipeline(document, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser p = new XMLParser(worker);
document.Open();
using(var html = new StringReader(HtmlData)) {
p.Parse(html); // <-- ERROR thrown here
}
// close document tried docoment.Close(); same issue
}
}
// get bytes from stream
pdf = stream.ToArray();
}
}
页面事件如下:
public class HeaderFooter: PdfPageEventHelper {
protected ElementList header;
protected ElementList footer;
private string _footerText;
private string _headerText;
public HeaderFooter(string headerText, string footerText) {
header = XMLWorkerHelper.ParseToElementList(headerText, null);
footer = XMLWorkerHelper.ParseToElementList(footerText, "table { font-size: 8px; font-style: italic; }");
_footerText = footerText;
_headerText = headerText;
}
public override void OnEndPage(PdfWriter writer, Document document) {
try {
footer = XMLWorkerHelper.ParseToElementList(_footerText.Replace("@PageNumber", writer.PageNumber.ToString()), "table { font-size: 8px; font-style: italic; }");
ColumnText ct = new ColumnText(writer.DirectContent);
ct.SetSimpleColumn(new Rectangle(36, 832, 559, 810));
foreach(IElement e in header) {
ct.AddElement(e);
}
ct.Go();
ct.SetSimpleColumn(new Rectangle(36, 10, 559, 32));
foreach(IElement e in footer) {
ct.AddElement(e);
}
ct.Go();
} catch (DocumentException de) {
throw new Exception();
}
}
}
在将 PdfWriter
放入 using
语句之前曾遇到过类似问题。这是一个基于您的问题的简化示例,您可以测试以重现该问题:
// ObjectDisposedException: Cannot access a closed Stream.
using (var stream = new MemoryStream())
{
using (var document = new Document())
{
using (var writer = PdfWriter.GetInstance(document, stream))
{
document.Open();
document.Add(new Chunk("test"));
}
}
pdf = stream.ToArray();
}
该代码片段抛出 ObjectDisposedException
:无法访问已关闭的流。 如您所述。
相反,如果 PdfWriter
是 Dispose()
这样的:
PdfWriter writer = null;
try
{
using (var stream = new MemoryStream())
{
using (var document = new Document())
{
writer = PdfWriter.GetInstance(document, stream);
document.Open();
document.Add(new Chunk("test"));
}
pdf = stream.ToArray();
}
}
finally { writer.Dispose(); }
一切顺利。 iTextSharp v5.5.8.
这原来是正在使用的 html 的问题。尽管页面在没有 header 的情况下生成的 PDF 完全正常,但在添加 header 时它会失败。使用和 returns 都很好。
添加PageEvent生成Header和Footer时,关闭后好像在尝试写入stream。我不确定将页面事件放在哪里。如果我删除页面事件,它会生成 pdf 文件。
p.Parse(html);
是 "Cannot access a closed Stream" 失败的地方。删除 writer.PageEvent
将导致 Parse 工作,但它不会生成 header/footer.
我使用 this 页面作为 header/footer 代码的参考。
代码:
try {
using(var stream = new MemoryStream()) {
using(var document = new Document(PageSize.LETTER, 20 f, 20 f, 5 f, 5 f)) {
using(var writer = PdfWriter.GetInstance(document, stream)) {
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
writer.PageEvent = new HeaderFooter(Header, Footer); // if I remove this it generates fine but then I don't get a header/footer.
var tagProcessors = (DefaultTagProcessorFactory) Tags.GetHtmlTagProcessorFactory();
tagProcessors.RemoveProcessor(HTML.Tag.IMG); // remove the default processor
tagProcessors.AddProcessor(HTML.Tag.IMG, new CustomImageTagProcessor()); // use our new processor
htmlContext.SetTagFactory(tagProcessors);
ICSSResolver CssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
CssResolver.AddCss(Css, true);
IPipeline pipeline =
new CssResolverPipeline(CssResolver,
new HtmlPipeline(htmlContext,
new PdfWriterPipeline(document, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser p = new XMLParser(worker);
document.Open();
using(var html = new StringReader(HtmlData)) {
p.Parse(html); // <-- ERROR thrown here
}
// close document tried docoment.Close(); same issue
}
}
// get bytes from stream
pdf = stream.ToArray();
}
}
页面事件如下:
public class HeaderFooter: PdfPageEventHelper {
protected ElementList header;
protected ElementList footer;
private string _footerText;
private string _headerText;
public HeaderFooter(string headerText, string footerText) {
header = XMLWorkerHelper.ParseToElementList(headerText, null);
footer = XMLWorkerHelper.ParseToElementList(footerText, "table { font-size: 8px; font-style: italic; }");
_footerText = footerText;
_headerText = headerText;
}
public override void OnEndPage(PdfWriter writer, Document document) {
try {
footer = XMLWorkerHelper.ParseToElementList(_footerText.Replace("@PageNumber", writer.PageNumber.ToString()), "table { font-size: 8px; font-style: italic; }");
ColumnText ct = new ColumnText(writer.DirectContent);
ct.SetSimpleColumn(new Rectangle(36, 832, 559, 810));
foreach(IElement e in header) {
ct.AddElement(e);
}
ct.Go();
ct.SetSimpleColumn(new Rectangle(36, 10, 559, 32));
foreach(IElement e in footer) {
ct.AddElement(e);
}
ct.Go();
} catch (DocumentException de) {
throw new Exception();
}
}
}
在将 PdfWriter
放入 using
语句之前曾遇到过类似问题。这是一个基于您的问题的简化示例,您可以测试以重现该问题:
// ObjectDisposedException: Cannot access a closed Stream.
using (var stream = new MemoryStream())
{
using (var document = new Document())
{
using (var writer = PdfWriter.GetInstance(document, stream))
{
document.Open();
document.Add(new Chunk("test"));
}
}
pdf = stream.ToArray();
}
该代码片段抛出 ObjectDisposedException
:无法访问已关闭的流。 如您所述。
相反,如果 PdfWriter
是 Dispose()
这样的:
PdfWriter writer = null;
try
{
using (var stream = new MemoryStream())
{
using (var document = new Document())
{
writer = PdfWriter.GetInstance(document, stream);
document.Open();
document.Add(new Chunk("test"));
}
pdf = stream.ToArray();
}
}
finally { writer.Dispose(); }
一切顺利。 iTextSharp v5.5.8.
这原来是正在使用的 html 的问题。尽管页面在没有 header 的情况下生成的 PDF 完全正常,但在添加 header 时它会失败。使用和 returns 都很好。