I'm creating a PDF file on the fly using ITextSharp and ASP.NET 1.1. My process is as follows -
What I'd like to do is delete the PDF from the server as soon it is displayed in the users browser. The PDF file is large so it is not an option to hold it in memory, an initial write to the server is required. I'm currently using a solution that periodically polls for files then deletes them, but I'd prefer a solution that deletes the file immediately after it has been downloaded to the client machine. Is there a way to do this?
You can't disable the Download button in your PDF files, and you sure can't prevent the user from choosing Print... in the right-click menu for the entire screen. What you can do is password protect your PDF in Adobe Acrobat. Aside from password protection, their Protect tool also allows you to disable printing.
Creating a dynamic PDF document is a good way to create an interactive slideshow. You can create interactive documents with buttons, movies and sound clips, hyperlinks, bookmarks, and page transitions. You can also set up documents in InDesign that can be converted to forms in Acrobat.
Instead of redirecting the browser to the created file you could serve the file yourself using you own HttpHandler. Then you could delete the file immediately after you served it or you could even create the file in memory.
Write the PDF file directly to the Client:
public class MyHandler : IHttpHandler {
public void ProcessRequest(System.Web.HttpContext context) {
context.Response.ContentType = "application/pdf";
// ...
PdfWriter.getInstance(document, context.Response.OutputStream);
// ...
or read an already generated file 'filename', serve the file, delete it:
context.Response.Buffer = false;
context.Response.BufferOutput = false;
context.Response.ContentType = "application/pdf";
Stream outstream = context.Response.OutputStream;
FileStream instream =
new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = instream.Read(buffer, 0, BUFFER_SIZE)) > 0) {
outstream.Write(buffer, 0, len);
}
outstream.Flush();
instream.Close();
// served the file -> now delete it
File.Delete(filename);
I didn't try this code. This is just how I think it would work ...
Inspired by f3lix's answer (thanks f3lix!) I've come up with the folowing VB.net code -
HttpContext.Current.Response.ClearContent()
HttpContext.Current.Response.ClearHeaders()
HttpContext.Current.Response.ContentType = "application/pdf"
HttpContext.Current.Response.TransmitFile(PDFFileName)
HttpContext.Current.Response.Flush()
HttpContext.Current.Response.Close()
File.Delete(PDFFileName)
This appears to work - is the 'WriteFile' method I've used any less efficent that the stream methods used by f3lix? Is there a method available that's more efficient than either of our solutions?
EDIT (19/03/2009) Based on comments below I've changed 'WriteFile' method to 'TransmitFile' as it appears it sends the file down to client in chunks rather than writing the entire file to the webserver's memory before sending. Further info can be found here.
Or you could just return it to the browser without writing to disk at all:
byte[] pdf;
using (MemoryStream ms = new MemoryStream()) {
Document doc = new Document();
PdfWriter.GetInstance(doc, ms);
doc.AddTitle("Document Title");
doc.Open();
doc.Add(new Paragraph("My paragraph."));
doc.Close();
pdf = ms.GetBuffer();
}
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=MyDocument.pdf");
Response.OutputStream.Write(pdf, 0, pdf.Length);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With