Question 298829 describes how linearizing your PDFs lets them stream page-by-page into the user's browser, so the user doesn't have to wait for the whole document to download before starting to view it. We have been using such PDFs successfully, but now have a new wrinkle: We want to keep the page-by-page streaming, but we also want to insert a fresh cover page at the front of the PDF documents each time we serve them up. (The cover-page will have time-sensitive information, such as the date, so it's not practical to include the cover page in the PDFs on disk.)
To help with this, are there any PDF libraries that can quickly append a cover page to a pre-linearized PDF and yield a streamable, linearized PDF as output? What's of the greatest concern is not the total time to merge the PDFs, but how soon we can start streaming part of the merged document to the user.
We were trying to do this with itextsharp, but it turns out that library can't output linearized PDFs. (See http://itext.ugent.be/library/question.php?id=21) Nonetheless, the following ASP.NET/itextsharp scratch code demonstrates the sort of API we're thinking of. In particular, if itextsharp always output linearized PDFs, something like this might already be the solution:
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();
}
}
}
Ideally we're looking for a .NET library, but it would be worth hearing about any other options as well.