Guilherme Flores
Guilherme Flores

Reputation: 399

Fail to open merged pdf created with ITextSharp

I'm trying to merge some PDFs and save it to a blob storage in azure, the file is saving in azure I can see the Kbs there and download the file, but when I try to open it I get the "Failed to load PDF document"

public static bool MergePDFsAzure(IEnumerable<string> fileNames, string targetPdf, bool deleteInputFiles)
    {
        Stream finalStream = new MemoryStream();

        iTextSharp.text.Document document = new iTextSharp.text.Document();
        iTextSharp.text.pdf.PdfCopy copy = new iTextSharp.text.pdf.PdfCopy(document, finalStream);

        iTextSharp.text.pdf.PdfReader.unethicalreading = true;
        try
        {
            copy.Open();
            document.Open();
            foreach (string file in fileNames)
            {
                var ms = new MemoryStream(File.ReadAllBytes(file)) {
                    Position = 0 
                };

                copy.AddDocument(new PdfReader(ms));
                ms.Dispose();
            }
        }
        catch (Exception ex)
        {
            ...

        }
        finally
        {
            if (document != null)
            {
                finalStream.Position = 0;
                StorageUtil.SaveFileAzure(...);
                document.Close();
                copy.Close();
            }
        }

    }

If I close the document before send to azure it crashes because the stream is disposed too.

Upvotes: 1

Views: 579

Answers (1)

mkl
mkl

Reputation: 95918

You have to close the document before sending the result to Azure. Otherwise the result simply is unfinished.

Unfortunately for your usage, though, the itext PdfCopy (and also the PdfWriter and the PdfStamper) closes its target stream when being closed itself implicitly during document.Close().

To prevent that, you can ask itext not to do so by setting

copy.CloseStream = false;

before closing the document.

Alternatively you can retrieve the byte array represented by the memory stream with finalStream.ToArray() and use that byte array instead of a stream to store data elsewhere. Retrieving this byte array is also possible in case of closed memory streams.

Upvotes: 2

Related Questions