将html转换为pdf并将其与现有pdf合并

时间:2017-03-23 16:44:48

标签: c# itext

我有一个System.Net.Mail.MailMessage,它将html body pdf附件转换为单个pdf。

使用this answer

将html正文转换为pdf

将pdf附件转换为一个pdf适用于this answer

然而,经过大约10个小时的尝试,我无法想出一个两者兼而有之的组合解决方案。所有我得到的都是IText源代码中的NullReferenceExceptions,"文档未打开"等...

例如,这不会引发错误,但生成的pdf只包含附件,但不包含html电子邮件正文:

Document document = new Document();
StringReader sr = new StringReader(mail.Body);
HTMLWorker htmlparser = new HTMLWorker(document);
using (FileStream fs = new FileStream(targetPath, FileMode.Create))
{
    PdfCopy writer = new PdfCopy(document, fs);
    document.Open();
    htmlparser.Parse(sr);

    foreach (string fileName in pdfList)
    {
        PdfReader reader = new PdfReader(fileName);
        reader.ConsolidateNamedDestinations();
        for (int i = 1; i <= reader.NumberOfPages; i++)
        {
            PdfImportedPage page = writer.GetImportedPage(reader, i);
            writer.AddPage(page);
        }
        PRAcroForm form = reader.AcroForm;
        if (form != null)
        {
            writer.CopyAcroForm(reader);
        }
        reader.Close();
    }
    writer.Close();
    document.Close();
}

我使用LGPL许可的ITextSharp 4.1.6

1 个答案:

答案 0 :(得分:1)

从v4.1.6粉丝到v4.1.6粉丝:D

看起来HTMLWorker正在解析后立即关闭文档流。因此,作为一种解决方法,您可以在内存中从邮件主体创建pdf。然后将此附件与附件一起添加到最终的pdf中。

以下是一些代码,应该可以解决这个问题:

  StringReader htmlStringReader = new StringReader("<html><body>Hello World!!!!!!</body></html>");

  byte[] htmlResult;

  using (MemoryStream htmlStream = new MemoryStream())
  {
    Document htmlDoc = new Document();
    PdfWriter htmlWriter = PdfWriter.GetInstance(htmlDoc, htmlStream);
    htmlDoc.Open();

    HTMLWorker htmlWorker = new HTMLWorker(htmlDoc);
    htmlWorker.Parse(htmlStringReader);

    htmlDoc.Close();
    htmlResult = htmlStream.ToArray();
  }

  byte[] pdfResult;

  using (MemoryStream pdfStream = new MemoryStream())
  {
    Document doc = new Document();
    PdfCopy copyWriter = new PdfCopy(doc, pdfStream);
    doc.Open();

    PdfReader htmlPdfReader = new PdfReader(htmlResult);
    AppendPdf(copyWriter, htmlPdfReader); // your foreach pdf code here
    htmlPdfReader.Close();

    PdfReader attachmentReader = new PdfReader("C:\\temp\\test.pdf");
    AppendPdf(copyWriter, attachmentReader);
    attachmentReader.Close();

    doc.Close();

    pdfResult = pdfStream.ToArray();
  }

  using (FileStream fs = new FileStream("C:\\temp\\test2.pdf", FileMode.Create, FileAccess.Write))
  {
    fs.Write(pdfResult, 0, pdfResult.Length);
  }

private void AppendPdf(PdfCopy writer, PdfReader reader)
{
  for (int i = 1; i <= reader.NumberOfPages; i++)
  {
    PdfImportedPage page = writer.GetImportedPage(reader, i);        
    writer.AddPage(page);
  }
}

Ofc你可以直接使用FileStream代替最终文档而不是MemoryStream。