2016-03-01 5 views
0

Когда объект PageEvent добавлен для создания верхнего и нижнего колонтитула, кажется, он пытается записать в поток после его закрытия. Я не уверен, где разместить событие страницы. Если я удаляю событие страницы, он генерирует PDF-файл.PageEvent бросает вызов Не удается получить доступ к закрытому потоку

p.Parse(html);, где «Не удается получить доступ к закрытому потоку» не удается. Удаление writer.PageEvent приведет к тому, что Parse будет работать, но тогда он не будет генерировать верхний/нижний колонтитул.

Я использовал страницу this как ссылку для кода верхнего колонтитула.

Код:

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

Использование 5.5.5.0 (это то, что у меня есть локально). Я получаю исключение en на одной из закрывающих скобок 'using'. Однако, если я раскомментирую метод 'document.Close()' после блока 'StringReader', он работает так, как ожидалось. –

+0

Ваш '{...} catch (DocumentException de) { throw new Exception(); } 'скрывает любую информацию, которую может содержать« DocumentException ». Запишите 'DocumentException' и ** не ** бросайте' new Exception() '. Кроме того, как @kuujinbo предлагает и перемещает 'PdfWriter' из' use'. «PdfWriter» автоматически закрывается, закрывая или удаляя «документ». Не каждый экземпляр одноразового использования должен быть помещен в инструкцию 'using' ... – mkl

+0

PDF генерирует штраф, если у меня есть использование или нет, пока я не добавлю PageEvent. Ошибка, созданная с помощью pageevent и не использующая, - это 'iTextSharp.tool.xml.pipeline.css.CssResolverPipeline крики, он не может найти собственный контекст.}} ITextSharp.tool.xml.pipeline.css.CssResolverPipeline кричит, он не может найти собственный контекст « – lucuma

ответ

0

Это оказалось проблемой при использовании html. Хотя страница сгенерировала PDF полностью без заголовка, она не сработает, если заголовок будет добавлен. Прибыль и прибыль были прекрасны.

+0

*« Учет и возврат были прекрасны ». * - Нет, это не так, не все из них по крайней мере. Они могут быть не проблемой в положительном случае, но в случае исключения они делают ситуацию хуже, чем необходимо. – mkl

+0

У меня не было проблем с кодом в моем проекте, генерирующим pdf. Единственная проблема, с которой я столкнулся, - это заголовок. – lucuma

1

видел подобные вопросы перед тем, связанных с положить 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: Не удается получить доступ к закрытой Stream., как вы описали.

Вместо этого, если 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.

+0

PDF генерирует штраф, пока я не добавлю PageEvent в обоих случаях (с использованием или без использования). Если я удаляю событие страницы в обоих случаях, файл pdf создается отлично. Так что, если сказать, что ошибка, полученная с помощью PageEvent, и не используется, - это крик iTextSharp.tool.xml.pipeline.css.CssResolverPipeline, он не может найти собственный контекст.}} ITextSharp.tool.xml.pipeline.css.CssResolverPipeline плачет , он не может найти собственный контекст. – lucuma

+1

На самом деле я бы вообще не предлагал «писатель». Когда «документ» размещен, единственным нетривиальным кодом является закрытие прослушивателей документов, а «писатель» - это * только * прослушиватель здесь. – mkl

+0

@mkl - Полностью согласен и вообще не ставит 'PdfWriter' в' using', не вызывает 'Dispose()' явно, но исходит из предпосылки, что OP имел свои причины т.е. организационные стандарты кодирования, которые определяют все классы, которые реализуют 'IDisposable', должны быть удалены. – kuujinbo

Смежные вопросы