0

I have a process where I am creating a PDF doc from data extracted from a MS SQL database. These are done with a person's name and I create a file in App_Data first with:

    string pdfTemp = System.Web.HttpContext.Current.Server.MapPath("~/Images/MTF.pdf");
    string filename = "~/App_Data/" + person.FirstName + "_" + person.LastName + "_MTF" + ".pdf";

    iTextSharp.text.pdf.PdfStamper stamper = new PdfStamper(reader, new FileStream(System.Web.HttpContext.Current.Server.MapPath(filename), FileMode.Create));

I then fill in the fields, close the stamper and send a stream to the view as well as save it to the database. I periodically try to delete any PDF file in the App_Data folder. If the PDF is being redone, sometimes the PDF in App_Data in still there for the person and it fails of course because is in use. How do you create a PDF without having to create a file first?

I've changed the approach according to a comment:

 MTFModel mtf = new MTFModel();
            mtf = GetMtfModelByPatientId(patientId);
            string pdfTemp = System.Web.HttpContext.Current.Server.MapPath("~/Images/MTF.pdf");
            iTextSharp.text.pdf.PdfReader reader = new PdfReader(pdfTemp);

            string pwd = System.Web.Security.Membership.GeneratePassword(20, 5);
            MemoryStream ms = new MemoryStream();
            iTextSharp.text.pdf.PdfStamper stamper = new PdfStamper(reader, ms);
            // stamp the form
            stamper.Close();
            return ms;

I can try to save it to the database:

            AddPatientMtf(mtd.ID, ms);

And then return the stream:

            return ms;

But the add patient function has to close the stream in order to save it.

Dean.DePue
  • 1,013
  • 1
  • 21
  • 45
  • 2
    If you don't want to create a `FileStream`, use `MemoryStream` to create the file in memory instead of writing it to disk. – Bruno Lowagie Jul 12 '17 at 09:39
  • @BrunoLowagie Thank you, I tried that approach, it seems to create the memory stream OK but when I do a BinaryWrite the bytes (after copying the stream array to a byte array the Adobe will not open it, says it is corrupt. Any ideas? – Dean.DePue Jul 13 '17 at 09:29
  • Well, maybe you didn't do it correctly. It works perfectly for the people who answered the question [Create PDF in memory instead of physical file](https://stackoverflow.com/questions/2815761/create-pdf-in-memory-instead-of-physical-file). Especially [this answer](https://stackoverflow.com/a/2824284/1622493) will be useful. – Bruno Lowagie Jul 13 '17 at 09:38
  • @BrunoLowagie thank You - I'm still getting a corrupt file. I've changed it now to create the memory stream as the stamper, fill in the fields, save it to the database as a byte array, then pulling it out and sending to the view. I'll update my question. – Dean.DePue Jul 13 '17 at 10:06
  • Are you sure you closed the `stamper` instance? Without `stamper.Close();` you cannot get a valid PDF document. I mean: you *say* you close the `stamper`, but you aren't showing much of your code. However, if the code to write the file on disk creates valid PDF files, there is *no reason whatsoever* why the bytes created in memory wouldn't be valid PDF. – Bruno Lowagie Jul 13 '17 at 10:07
  • What I really dislike about your "new" design, is the detour you make saving the files into a database. Why is that necessary? Why would you risk all the encoding problems related to storing and retrieving a *binary* file to and from a database if you don't even want to keep a copy of the file? – Bruno Lowagie Jul 13 '17 at 10:11
  • @BrunoLowagie Thank You. The only reason I save it to the DB is so that I don't have to generate the form every time the user wants to see it. You are right, if I close the stamper and return the stream it works fine. But that just means that I have to recreate it every time. – Dean.DePue Jul 13 '17 at 10:22
  • *If I close the stamper and return the stream it works fine, but that just means that I have to recreate it every time.* That is illogical. If it works fine when you return the stream, you have proof that iText works exactly the way it should. If saving and retrieving the bytes to and from a database corrupts the bytes, you have an encoding problem. That is a totally different question that is hard to solve remotely, because we don't know anything about your database, how you store a BLOB, nor how you retrieve a BLOB. – Bruno Lowagie Jul 13 '17 at 10:25
  • @BrunoLowagie I've added the process how I save to the DB. It works fine when I pull the saved file into a stream and save that. – Dean.DePue Jul 13 '17 at 11:27
  • I don't understand why you still choose to update your question with the irrelevant stuff, leaving the relevant stuff out. You say that you can store the bytes of a PDF in a database, and then get those bytes and save them to a file that is a valid PDF. However, when you send those bytes to a browser instead of storing them in a file, things go wrong. OK, **then why don't I see that code in your question?** Clean up your question (it's too long to read by now), remove the irrelevant stuff, and limit it to the actual problem, which is not an iText problem based on what you say in your comments. – Bruno Lowagie Jul 13 '17 at 12:03
  • Your question is as simple as this: I have the bytes of a valid PDF in my database. I can retrieve those bytes from the database, and store them in a file. The file is a valid PDF file. However, when I retrieve the same bytes from the database, keep them in memory, and send them to a browser, the PDF received in the browser is corrupt. This is the code that shows how I serve the bytes to the browser: `...` – Bruno Lowagie Jul 13 '17 at 12:05

0 Answers0