12

How do one create PDF in memorystream instead of physical file using itext7? I have no idea how to do it in the latest version, any help?

I tried the following code, but pdfSM is not properly populated:

string filePath = "./abc.pdf";

MemoryStream pdfSM = new ByteArrayOutputStream();

PdfDocument doc = new PdfDocument(new PdfReader(filePath), new PdfWriter(pdfSM));
.......

doc.close();

The full testing code as below for your reference, it worked when past filePath into PdfWriter but not for the memory stream:

    public static readonly String sourceFolder = "../../FormTest/";

    public static readonly String destinationFolder = "../../Output/";

    static void Main(string[] args)
    {

        String srcFilePattern = "I-983";
        String destPattern = "I-129_2014_";

        String src = sourceFolder + srcFilePattern + ".pdf";
        String dest = destinationFolder + destPattern + "_flattened.pdf";
        MemoryStream returnSM = new MemoryStream();

        PdfDocument doc = new PdfDocument(new PdfReader(src), new PdfWriter(returnSM));

        PdfAcroForm form = PdfAcroForm.GetAcroForm(doc, false);

        foreach (PdfFormField field in form.GetFormFields().Values) 
        {
            var fieldName = field.GetFieldName();
            var type = field.GetType();
            if (fieldName != null)
            {
                if (type.Name.Equals("PdfTextFormField"))
                {
                        field.SetValue("T");
                }
            }               
        }
        form.FlattenFields();         
        doc.Close();

    }
Danh
  • 5,916
  • 7
  • 30
  • 45
Zhao JIN
  • 121
  • 1
  • 1
  • 4
  • 1
    "pdfSM is not properly populated", can you please define what you actually mean by this? Are you getting any compilation errors? Are you getting any runtime errors? – Adrian Sanguineti Nov 11 '16 at 03:55
  • PdfWriter class supports filePath as constructor as well as stream, when i passed in the path, it worked with PDF created, however, passing Stream didn't return anything, there is no compilation or runtime error, because am newer to iText, maybe i just didn't know how to use this class, that's why i need help – Zhao JIN Nov 11 '16 at 05:21
  • I don't see you closing the `doc`, nor do i see you retrieving data gem the stream. – mkl Nov 11 '16 at 05:35
  • Is it possible to save file to Memory Stream without creating physically file? – Zhao JIN Nov 11 '16 at 06:45
  • 1
    @ZachJinUS-Advisory Yes, but I don't see you closing the `doc` anywhere, hence it is very probable that the full PDF is never written to the `MemoryStream`. (Which would explain your problem.) Or maybe you're using the wrong method to get the `byte[]` from the `MemoryStream`. It's hard to tell since you've posted less than half of a question. – Bruno Lowagie Nov 11 '16 at 07:12

3 Answers3

21

This works for me.

    public byte[] CreatePdf()
    {
        var stream = new MemoryStream();
        var writer = new PdfWriter(stream);
        var pdf = new PdfDocument(writer);
        var document = new Document(pdf);

        document.Add(new Paragraph("Hello world!"));
        document.Close();

        return stream.ToArray();
    }
Fred
  • 12,086
  • 7
  • 60
  • 83
  • 3
    Hi Fred, it's not right. When you close a document, the MemoryStream in PdfWriter also closes because it is IDisposable and `stream.dispose()` is called immediately when `document.Close()` is called. An exception is thrown when trying to access the stream: System.ObjectDisposedException: 'Cannot access a closed Stream.' – Puty Feb 12 '20 at 11:03
  • But I used this code yesterday and it works for me. – Fred Feb 12 '20 at 11:32
  • Are you sure you are using iText 7? Because I'm working with it now and it doesn't work. – Puty Feb 12 '20 at 12:34
  • Yes, I just tried this exact code (in a console application) and can confirm that it works on with iText 7 version 7.1.9 on .NET Core 3.1. – Fred Feb 12 '20 at 12:38
  • Interesting, I use it in .NET Standard 2.0 and this code doesn't work for me. And I Use iText 7.1.9 too, instaled from nuget – Puty Feb 12 '20 at 12:58
  • And it worrk when you use existing pdf file? not created, but loaded. – Puty Feb 12 '20 at 13:01
  • I would not know how it would work when modified to use an existing PDF file. This code is purely for *creating a new* PDF in-memory as a byte array. – Fred Feb 12 '20 at 13:20
  • Yes. Freds solution works with .NET Framework 4.6. And if I don't close the document, it's corrupt. Thanks Fred – alex Mar 19 '20 at 14:38
  • Thanks so much for your answer – Jorge Luis Alcantara Nov 20 '20 at 16:06
  • 3
    I had ObjectDisposedException with .NET Standard 2.0 as well. Adding this line solves the issue: writer.SetCloseStream(false); – ChelowekKot Dec 09 '20 at 09:45
3

I needed the same thing. Got it working like this: (I included some settings which improve performance)

 string HtmlString = "<html><head></head><body>some content</body></html>";
 byte[] buffer;
 PdfDocument pdfDoc = null;
 using (MemoryStream memStream = new MemoryStream())
 {
     using(PdfWriter pdfWriter = new PdfWriter(memStream, wp))
     {
        pdfWriter.SetCloseStream(true);
        using (pdfDoc = new PdfDocument(pdfWriter))
        {
           ConverterProperties props = new ConverterProperties();

           pdfDoc.SetDefaultPageSize(PageSize.LETTER);
           pdfDoc.SetCloseWriter(true);
           pdfDoc.SetCloseReader(true);
           pdfDoc.SetFlushUnusedObjects(true);
           HtmlConverter.ConvertToPdf(HtmlString, pdfDoc, props));
           pdfDoc.Close();
        }
     }
     buffer = memStream.ToArray();
 }
 return buffer;
Uriel Fernandez
  • 101
  • 1
  • 5
2

iText7、C# Controller

Error:

public ActionResult Report()
{
    //...
    doc1.Close();
    return File(memoryStream1, "application/pdf", "pdf_file_name.pdf");
}

Work:

public ActionResult Report()
{
    //...
    doc1.Close();
    byte[] byte1 = memoryStream1.ToArray();
    return File(byte1, "application/pdf", "pdf_file_name.pdf");
}

I don't know why... but, it's working!

another: link