问题 298829描述了如何将 PDF 线性化让它们逐页流式传输到用户的浏览器中,因此用户不必等待整个文档下载后即可开始查看。我们一直在成功地使用此类 PDF,但现在有一个新问题:我们希望保持逐页流式传输,但我们还希望在每次提供 PDF 文档时在其前面插入一个新的封面. (封面将包含时间敏感信息,例如日期,因此将封面包含在磁盘上的 PDF 中是不切实际的。)
为了解决这个问题,是否有任何 PDF 库可以快速将封面附加到预线性化的 PDF 并生成可流式传输的线性化 PDF 作为输出?最关心的不是合并 PDF 的总时间,而是我们多久可以开始将合并文档的一部分流式传输给用户。
我们试图用 itextsharp 做到这一点,但事实证明该库无法输出线性化的 PDF。(请参阅http://itext.ugent.be/library/question.php?id=21)尽管如此,以下 ASP.NET/itextsharp 临时代码演示了我们正在考虑的那种 API。特别是,如果 itextsharp 总是输出线性化的 PDF,这样的解决方案可能已经是:
public class StreamPdf : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/pdf";
RandomAccessFileOrArray ramFile = new RandomAccessFileOrArray(@"C:\bigpdf.pdf");
PdfReader reader1 = new PdfReader(ramFile, null);
Document doc = new Document();
// We'll stream the PDF to the ASP.NET output
// stream, i.e. to the browser:
PdfWriter writer = PdfWriter.GetInstance(doc, context.Response.OutputStream);
writer.Open();
doc.Open();
PdfContentByte cb = writer.DirectContent;
// output cover page:
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
Font font = new Font(bf, 11, Font.NORMAL);
ColumnText ct = new ColumnText(cb);
ct.SetSimpleColumn(60, 300, 600, 300 + 28 * 15, 15, Element.ALIGN_CENTER);
ct.AddText(new Phrase(15, "This is a cover page information\n", font));
ct.AddText(new Phrase(15, "Date: " + DateTime.Now.ToShortDateString() + "\n", font));
ct.Go();
// output src document:
int i = 0;
while (i < reader1.NumberOfPages)
{
i++;
// add next page from source PDF:
doc.NewPage();
PdfImportedPage page = writer.GetImportedPage(reader1, i);
cb.AddTemplate(page, 0, 0);
// use something like this to flush the current page to the
// browser:
writer.Flush();
s.Flush();
context.Response.Flush();
}
doc.Close();
writer.Close();
s.Close();
}
}
}
理想情况下,我们正在寻找一个 .NET 库,但也值得了解任何其他选项。