当前位置: 首页 > 知识库问答 >
问题:

使用IText7生成一个包含从html转换的多页的pdf文档

孟征
2023-03-14

我正在使用IText 7,我已经能够获得一个html页面并为该页面生成pdf,但我需要从多个html页面生成一个pdf文档,并用页面分隔。例如:我有Page1。html第2页。html和第3页。html。我需要一份3页的pdf文档,第一页的内容为Page1。html,第二页,内容为第2页。html之类的。。。

这是我的代码,它适用于一个html页面:

ConverterProperties properties = new ConverterProperties();              
PdfWriter writer = new PdfWriter(pdfRoot, new WriterProperties().SetFullCompressionMode(true));
PdfDocument pdfDocument = new PdfDocument(writer);
pdfDocument.AddEventHandler(PdfDocumentEvent.END_PAGE, new HeaderPdfEventHandler());
HtmlConverter.ConvertToPdf(htmlContent, pdfDocument, properties);

是否可以针对多个html页面进行循环,为每个html页面向PdfDocument添加一个新页面,然后仅生成一个pdf,每个html页面生成一个页面?

更新

我一直在遵循这个示例,并试图将其从Java转换为C#,我试图使用PdfMerger并循环html页面。。。但我收到了异常情况无法访问封闭流,在这一行:

temp = new PdfDocument(
                    new PdfReader(new RandomAccessSourceFactory().CreateSource(baos), rp));

它看起来像是与ByteArrayOutputStream baos实例相关。有什么建议吗?这是我当前的代码:

foreach (var html in htmlList)
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PdfDocument temp = new PdfDocument(new PdfWriter(baos));
    HtmlConverter.ConvertToPdf(html, temp, properties);              
    ReaderProperties rp = new ReaderProperties();
    temp = new PdfDocument(
        new PdfReader(new RandomAccessSourceFactory().CreateSource(baos), rp));
    merger.Merge(temp, 1, temp.GetNumberOfPages());
    temp.Close();
}
pdfDocument.Close();

共有2个答案

程磊
2023-03-14

也许不那么简洁。我用“使用”。类似的回答

private byte[] CreatePDF(string html)
    {
        byte[] binData;

        using (var workStream = new MemoryStream())
        {
            using (var pdfWriter = new PdfWriter(workStream))
            {
                //Create one pdf document
                using (var pdfDoc = new PdfDocument(pdfWriter))
                {                        
                    pdfDoc.SetDefaultPageSize(iText.Kernel.Geom.PageSize.A4.Rotate());
                    //Create one pdf merger
                    var pdfMerger = new PdfMerger(pdfDoc);
                    //Create two identical pdfs
                    for (int i = 0; i < 2; i++)
                    {
                        using (var newStream = new MemoryStream(CreateDocument(html)))
                        {
                            ReaderProperties rp = new ReaderProperties();
                            using (var newPdf = new PdfDocument(new PdfReader(newStream, rp)))
                            {
                                pdfMerger.Merge(newPdf, 1, newPdf.GetNumberOfPages());
                            }
                        }
                    }
                }
                binData = workStream.ToArray();
            }
        }
        return binData;
    }

创建pdf

private byte[] CreateDocument(string html)
    {
        byte[] binData;

        using (var workStream = new MemoryStream())
        {
            using (var pdfWriter = new PdfWriter(workStream))
            {
                using (var pdfDoc = new PdfDocument(pdfWriter))
                {
                    pdfDoc.SetDefaultPageSize(iText.Kernel.Geom.PageSize.A4.Rotate());

                    ConverterProperties props = new ConverterProperties();
                    using (var document = HtmlConverter.ConvertToDocument(html, pdfDoc, props))
                    {                            
                    }
                }
                binData = workStream.ToArray();
            }
        }
        return binData;
    }
易英奕
2023-03-14

您使用的是RandomAccessSourceFactory,并向其中传递一个封闭流,您将PDF文档写入其中RandomAccessSourceFactory需要一个准备好读取的输入流。

首先,您应该使用本机的MemoryStream。ByteArrayOutputStream是为内部目的从Java移植的类(尽管它也扩展了MemoryStream)。其次,您不必使用RlandAccessSourceFactory-有一个更简单的方法。

您可以使用用于创建临时PDF的MemoryStream的字节创建一个新的MemoryStream实例,如下所示:

baos = new MemoryStream(baos.ToArray());

另外,最好直接关闭PdfMerger实例,而不是关闭文档-关闭PdfMerger也会关闭底层文档。

总之,我们得到了以下代码:

foreach (var html in htmlList)
{
    MemoryStream baos = new MemoryStream();
    PdfDocument temp = new PdfDocument(new PdfWriter(baos));
    HtmlConverter.ConvertToPdf(html, temp, properties);              
    ReaderProperties rp = new ReaderProperties();
    baos = new MemoryStream(baos.ToArray());
    temp = new PdfDocument(new PdfReader(baos, rp));
    pdfMerger.Merge(temp, 1, temp.GetNumberOfPages());
    temp.Close();
}
pdfMerger.Close();
 类似资料:
  • 我知道如何生成单个超文本标记语言页面。我想知道如何从多个超文本标记语言页面生成的pdf生成单个pdf页面。 例如,有和另一个文件我可以生成单独的pdf文件和分别来自html。我可以将它们写入文件系统,然后像iTextConcatenate示例中那样连接它们。 我只是想知道我是否可以在不将它们写入文件系统的情况下动态地组合此操作。我无法识别丢失的链接

  • 我有这种超文本标记语言: HTML只包含生成的PDF文件中的文本,而忽略了图像。 这是我用来转换该段落的代码: 我使用的是iText7 7.1.11和iText7.pdfhtml3.0.0。 我还应该告诉你,使用iText7 7.1.2和iText7,同样的代码在同样的图像下工作得非常完美。PDFHTML2.0.2。 这些版本之间有什么变化吗? 当然,图像可以使用https://server/Us

  • 我想使用FlyingSaucer将一个包含阿拉伯字符的HTML页面转换为PDF文件,但生成的PDF不包含组合字符,并向后打印输出。 HTML: null null Java摘录: 我怎样做才能得到正确的结果?

  • 我已经使用chart.js来生成具有多个图表的报表页面。我需要将此报告导出为PDF。有许多解决方案可以通过搜索,但我找不到一个有多个画布元素。 唯一可用的解决方案似乎是遍历所有图像,并使用这些图像重新创建报告,然后将其作为pdf下载。 有没有更简单/更有效的方法来实现这一点?

  • 我正在将一些PDF编辑工具从iTextSharp更新到iText7。 在iTextSharp中,pdfStamper类中有一个方法:pdfStamper。ReplacePage()。然而,iText7中的pdfStamper类已被删除,我在复制相同的功能时遇到困难。 假设我有文档X,需要用文档Y的第1页替换第4页,但我希望结果保存到一个新的文档Z。 到目前为止,我有3行使用CopyPageTo方法

  • 我想从HTML模板中提取一部分,并将其转换为PDF文件,以便用户可以选择下载。(例如,单击按钮后)。 我找到了一个名为jsPDF的库,我将如何在Angular2应用程序(RC4)中使用jsPDF? 谢谢你