我需要将N个PDF文件合并为一个。我先创建一个空白文件
byte[] pdfBytes = null;
var ms = new MemoryStream();
var doc = new iTextSharp.text.Document();
var cWriter = new PdfCopy(doc, ms);
稍后我循环通过html strings array
foreach (NBElement htmlString in someElement.Children())
{
byte[] msTempDoc = getPdfDocFrom(htmlString.GetString(), cssString.GetString());
addPagesToPdf(cWriter, msTempDoc);
}
在getPdfDocFrom中,我使用XMLWorkerHelper创建pdf文件并将其作为字节数组返回
private byte[] getPdfDocFrom(string htmlString, string cssString)
{
var tempMs = new MemoryStream();
byte[] tempMsBytes;
var tempDoc = new iTextSharp.text.Document();
var tempWriter = PdfWriter.GetInstance(tempDoc, tempMs);
tempDoc.Open();
using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(cssString)))
{
using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(htmlString)))
{
//Parse the HTML
iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(tempWriter, tempDoc, msHtml, msCss);
tempMsBytes = tempMs.ToArray();
}
}
tempDoc.Close();
return tempMsBytes;
}
稍后我尝试将此PDF文件中的页面添加到空白页面。
private static void addPagesToPdf(PdfCopy mainDocWriter, byte[] sourceDocBytes)
{
using (var msOut = new MemoryStream())
{
PdfReader reader = new PdfReader(new MemoryStream(sourceDocBytes));
int n = reader.NumberOfPages;
PdfImportedPage page;
for (int i = 1; i <= n; i++)
{
page = mainDocWriter.GetImportedPage(reader, i);
mainDocWriter.AddPage(page);
}
}}
当它尝试从我传递给函数的字节数组创建PdfReader时,它会中断。 “重建失败:未找到预告片。;原始消息:未找到PDF startxref。”
之前我使用过另一个库来处理PDF。我传递了2个PdfDocuments作为对象,只是在循环中将页面从一个添加到另一个。它不支持Css,所以我不得不切换到ITextSharp。
我不太了解PdfWriter和PdfCopy之间的区别。
答案 0 :(得分:0)
代码中存在逻辑错误。如您在getPdfDocFrom()
方法中所做的那样,从头开始创建文档时,文档不会完成,直到您触发Close()
方法为止。在此Close()
方法中,将创建预告片以及交叉引用(外部参照)表。该错误告诉您缺少那些。
确实,您确实调用了Close()
方法:
tempDoc.Close();
但是当你Close()
文档时,为时已晚:你已经创建了tempMsBytes
数组。 关闭文档后,需要创建该数组。
修改:我对C#一无所知,但如果MemoryStream
在关闭它后清除其缓冲区,则可以使用mainDocWriter.CloseStream = false;
以便MemoryStream
关闭文档时,1}}没有关闭。
在Java中,设置&#34;关闭流&#34;是一个坏主意。参数为false。当我阅读问题Create PDF in memory instead of physical file的答案时,我发现C#可能并不总是需要额外的这一行。
备注:通过将PdfImportedPage
个实例添加到PdfWriter
来合并文件就是一个不好品味的例子。如果您使用的是iTextSharp 5或更早版本,则应使用PdfCopy
或PdfSmartCopy
来执行此操作。如果您使用PdfWriter
,则会丢弃大量信息(例如链接注释)。