页面事件正在引发无法访问已关闭的流

本文关键字:访问 事件 | 更新日期: 2023-09-27 18:36:54

当添加PageEvent以生成页眉和页脚时,它似乎在关闭流后尝试写入流。 我不确定将页面事件放在哪里。 如果我删除页面事件,它会生成 pdf 正常。

p.Parse(html);是"无法访问已关闭的流"失败的地方。 删除writer.PageEvent将导致解析工作,但随后不会生成页眉/页脚。

我使用此页面作为页眉/页脚代码的参考。

法典:

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

页面事件正在引发无法访问已关闭的流

之前见过与在using语句中放置PdfWriter有关的类似问题。下面是一个基于您的问题的简化示例,您可以测试以重现问题:

// 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的问题。 尽管页面在没有页眉的情况下生成了完全正常的 PDF,但在添加页眉时它会失败。 使用和退货都很好。