使用 IText 7 从 html 转换生成一个包含多个页面的 pdf 文档
Generate one pdf document with multiple pages converting from html using IText 7
我正在使用 IText 7
,我已经能够获得一个 html 页面并为该页面生成一个 pdf,但我需要从多个 html 页并以页分隔。例如:我有 Page1.html
、Page2.html
和 Page3.html
。我需要一个 3 页的 pdf 文档,第一页的内容为 Page1.html
,第二页的内容为 Page2.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 添加一个新页面,然后每个 html 仅生成一个页面一页的 pdf ] 页?
更新
我一直在关注 this 示例并尝试将其从 Java 转换为 C#,我正在尝试使用 PdfMerger
并围绕 html页面...但我在这一行收到异常 Cannot access a closed stream
:
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();
您正在使用 RandomAccessSourceFactory
并向其中传递一个您写入 PDF 文档的封闭流。 RandomAccessSourceFactory
需要一个准备好读取的输入流。
首先,您应该使用 .NET 世界原生的 MemoryStream
。 ByteArrayOutputStream
是出于内部目的从 Java 移植而来的 class(尽管它也扩展了 MemoryStream
)。其次,您不必使用 RandomAccessSourceFactory
- 有一种更简单的方法。
您可以使用以下行从用于创建临时 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();
也许不那么简洁。我用“使用”。 Similar answer
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;
}
我正在使用 IText 7
,我已经能够获得一个 html 页面并为该页面生成一个 pdf,但我需要从多个 html 页并以页分隔。例如:我有 Page1.html
、Page2.html
和 Page3.html
。我需要一个 3 页的 pdf 文档,第一页的内容为 Page1.html
,第二页的内容为 Page2.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 添加一个新页面,然后每个 html 仅生成一个页面一页的 pdf ] 页?
更新
我一直在关注 this 示例并尝试将其从 Java 转换为 C#,我正在尝试使用 PdfMerger
并围绕 html页面...但我在这一行收到异常 Cannot access a closed stream
:
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();
您正在使用 RandomAccessSourceFactory
并向其中传递一个您写入 PDF 文档的封闭流。 RandomAccessSourceFactory
需要一个准备好读取的输入流。
首先,您应该使用 .NET 世界原生的 MemoryStream
。 ByteArrayOutputStream
是出于内部目的从 Java 移植而来的 class(尽管它也扩展了 MemoryStream
)。其次,您不必使用 RandomAccessSourceFactory
- 有一种更简单的方法。
您可以使用以下行从用于创建临时 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();
也许不那么简洁。我用“使用”。 Similar answer
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;
}