Discussion:
[itextsharp-questions] MemoryStream object destroyed by PdfStamper.Close()
joebeazelman
2009-01-01 21:07:08 UTC
Permalink
For some odd reason, PdfStamper either closes or disposes my MemoryStream
object when its Close() method is called. I can't figure out why this is
happening. Thanks.

I get the following message:
System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="itextsharp"
StackTrace:
at iTextSharp.text.pdf.PdfWriter.get_PdfIndirectReference()
at iTextSharp.text.pdf.PdfImportedPage..ctor(PdfReaderInstance
readerInstance, PdfWriter writer, Int32 pageNumber)
at iTextSharp.text.pdf.PdfReaderInstance.GetImportedPage(Int32
pageNumber)
at iTextSharp.text.pdf.PdfCopy.GetImportedPage(PdfReader reader,
Int32 pageNumber)
at Solidwave.Forms.PDFOrder.CopyPages(Stream finalPdfStream,
MemoryStream stream, Int32 numberOfPages, Document doc) in
D:\GenerateOrderPDF\GenerateOrderPDF\PDFOrder.cs:line 64
at Solidwave.Forms.PDFOrder.Draw(Stream finalPdfStream) in
D:\GenerateOrderPDF\GenerateOrderPDF\PDFOrder.cs:line 50
at GenerateOrderPDF.Program.Main() in
D:\GenerateOrderPDF\GenerateOrderPDF\Program.cs:line 22
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[]
args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence
assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:

----------

class PDFOrderForm
{
private string _errorMsg = "";
public string ErrorMsg
{
get { return _errorMsg; }
set { _errorMsg = value; }
}

public void Draw(Stream finalPdfStream)
{
PdfReader firstSheetTemplateReader = new
PdfReader(@"D:\GenerateOrderPDF\GenerateOrderPDF\Invoice Template.pdf");
PdfReader secondSheetTemplateReader = new
PdfReader(@"D:\GenerateOrderPDF\GenerateOrderPDF\Invoice Template.pdf");

// create a new document to hold all final pages
Document doc = new Document();
MemoryStream tempStream;
doc.Open();
int numberOfPages = 0;

//
for (int i = 0; i < 2; i++)
{
// used to switch between first and second sheet
PdfReader templateReader = new
PdfReader(firstSheetTemplateReader);

// create a temporary memory stream for holding the generated
pages
tempStream = new System.IO.MemoryStream();

// fill out the form template fields
PdfStamper stamper = new PdfStamper(templateReader, tempStream);
AcroFields fields = stamper.AcroFields;
FillDocumentInfo(fields);
numberOfPages = FillOutDocumentDetails(templateReader, stamper,
fields);

// flatten the form
stamper.FormFlattening = true;
stamper.Close();

// copy all pages to the document
CopyPages(finalPdfStream, tempStream, numberOfPages, doc);
}

// close the document
doc.Close();
}

private static void CopyPages(Stream finalPdfStream, MemoryStream
stream, int numberOfPages, Document doc)
{
// copy all generated pages into final document
PdfCopy pdfcopy = new PdfCopy(doc, finalPdfStream);
PdfReader tempReader = new PdfReader(stream.ToArray());
for (int i = 1; i <= numberOfPages; i++)
{
pdfcopy.AddPage(pdfcopy.GetImportedPage(tempReader, i));
}
pdfcopy.FreeReader(tempReader);
}

private static int FillOutDocumentDetails(PdfReader templateReader,
PdfStamper stamper, AcroFields fields)
{
float[] tablePosition =
fields.GetFieldPositions("TABLE_PLACEHOLDER");

PdfContentByte overContent = stamper.GetOverContent(1);
int numberOfPages = templateReader.NumberOfPages;

ColumnText column = new ColumnText(overContent);
column.SetSimpleColumn(tablePosition[1], tablePosition[2],
tablePosition[3], tablePosition[4] - 0.5f, 0, Element.ALIGN_TOP);
float[] widths = { 0.1089f, 0.1089f, 0.5527f, 0.1149f, 0.1149f };

PdfPTable table = new PdfPTable(widths);
table.WidthPercentage = 100;
table.DefaultCell.BorderWidth = 0.0f;
table.DefaultCell.HasBorder(Rectangle.LEFT_BORDER);
//table.TotalWidth = tablePosition[3]-tablePosition[1];
table.SplitRows = true;

for (int j = 0; j < 500; j++)
{
PdfPCell cell = new PdfPCell();
cell.AddElement(new Chunk(j.ToString() + "we are the champions
my friends"));
table.AddCell(cell);
}
Rectangle r = new Rectangle(PageSize.A4.GetRight(72),
PageSize.A4.GetTop(72));

column.AddElement(table);
column.Go();

while (ColumnText.HasMoreText(column.Go()))
{
numberOfPages++;
stamper.InsertPage(numberOfPages,
templateReader.GetPageSizeWithRotation(1));
column.SetSimpleColumn(tablePosition[1], tablePosition[2],
tablePosition[3], tablePosition[4] + 250, 0, Element.ALIGN_TOP);
column.Canvas = stamper.GetOverContent(numberOfPages);
// reread the fill in form and add it to our document
}
return numberOfPages;
}

private static void FillDocumentInfo(AcroFields fields)
{
// fill out invoice information
fields.SetField("DOCUMENT_TITLE", "INVOICE");
fields.SetField("COMPANY_ADDRESS", "Blah");
fields.SetField("BILLING_ADDRESS", "Blah");
fields.SetField("SHIPPING_ADDRESS", "MBlah");
fields.SetField("DETAILS", "DATE: " +
DateTime.Now.ToString("MM/DD/YYYY"));
fields.SetField("STATUS", "Completed");
fields.SetField("SHIPPING_METHOD", "UPS");
fields.SetField("PAYMENT_METHOD", "VISA x1111");
fields.SetField("SHIPPING", "Done");
}
}
--
View this message in context: http://www.nabble.com/MemoryStream-object-destroyed-by-PdfStamper.Close%28%29-tp21244882p21244882.html
Sent from the itextsharp-questions mailing list archive at Nabble.com.
William Rickards
2009-01-01 22:11:17 UTC
Permalink
Does the pdf stamper have a method indicating not to close the stream
like the pdfwriter does?

ReportOutputStream = New System.IO.MemoryStream
m_wrtReport = iTextSharp.text.pdf.PdfWriter.GetInstance(m_docReport,
ReportOutputStream)
m_wrtReport.CloseStream = False

Will Rickards
Post by joebeazelman
For some odd reason, PdfStamper either closes or disposes my MemoryStream
object when its Close() method is called. I can't figure out why this is
happening. Thanks.
System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="itextsharp"
at iTextSharp.text.pdf.PdfWriter.get_PdfIndirectReference()
at iTextSharp.text.pdf.PdfImportedPage..ctor(PdfReaderInstance
readerInstance, PdfWriter writer, Int32 pageNumber)
at iTextSharp.text.pdf.PdfReaderInstance.GetImportedPage(Int32
pageNumber)
at iTextSharp.text.pdf.PdfCopy.GetImportedPage(PdfReader reader,
Int32 pageNumber)
at Solidwave.Forms.PDFOrder.CopyPages(Stream finalPdfStream,
MemoryStream stream, Int32 numberOfPages, Document doc) in
D:\GenerateOrderPDF\GenerateOrderPDF\PDFOrder.cs:line 64
at Solidwave.Forms.PDFOrder.Draw(Stream finalPdfStream) in
D:\GenerateOrderPDF\GenerateOrderPDF\PDFOrder.cs:line 50
at GenerateOrderPDF.Program.Main() in
D:\GenerateOrderPDF\GenerateOrderPDF\Program.cs:line 22
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[]
args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence
assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
----------
class PDFOrderForm
{
private string _errorMsg = "";
public string ErrorMsg
{
get { return _errorMsg; }
set { _errorMsg = value; }
}
public void Draw(Stream finalPdfStream)
{
PdfReader firstSheetTemplateReader = new
PdfReader secondSheetTemplateReader = new
// create a new document to hold all final pages
Document doc = new Document();
MemoryStream tempStream;
doc.Open();
int numberOfPages = 0;
//
for (int i = 0; i < 2; i++)
{
// used to switch between first and second sheet
PdfReader templateReader = new
PdfReader(firstSheetTemplateReader);
// create a temporary memory stream for holding the generated
pages
tempStream = new System.IO.MemoryStream();
// fill out the form template fields
PdfStamper stamper = new PdfStamper(templateReader, tempStream);
AcroFields fields = stamper.AcroFields;
FillDocumentInfo(fields);
numberOfPages = FillOutDocumentDetails(templateReader, stamper,
fields);
// flatten the form
stamper.FormFlattening = true;
stamper.Close();
// copy all pages to the document
CopyPages(finalPdfStream, tempStream, numberOfPages, doc);
}
// close the document
doc.Close();
}
private static void CopyPages(Stream finalPdfStream, MemoryStream
stream, int numberOfPages, Document doc)
{
// copy all generated pages into final document
PdfCopy pdfcopy = new PdfCopy(doc, finalPdfStream);
PdfReader tempReader = new PdfReader(stream.ToArray());
for (int i = 1; i <= numberOfPages; i++)
{
pdfcopy.AddPage(pdfcopy.GetImportedPage(tempReader, i));
}
pdfcopy.FreeReader(tempReader);
}
private static int FillOutDocumentDetails(PdfReader templateReader,
PdfStamper stamper, AcroFields fields)
{
float[] tablePosition =
fields.GetFieldPositions("TABLE_PLACEHOLDER");
PdfContentByte overContent = stamper.GetOverContent(1);
int numberOfPages = templateReader.NumberOfPages;
ColumnText column = new ColumnText(overContent);
column.SetSimpleColumn(tablePosition[1], tablePosition[2],
tablePosition[3], tablePosition[4] - 0.5f, 0, Element.ALIGN_TOP);
float[] widths = { 0.1089f, 0.1089f, 0.5527f, 0.1149f, 0.1149f };
PdfPTable table = new PdfPTable(widths);
table.WidthPercentage = 100;
table.DefaultCell.BorderWidth = 0.0f;
table.DefaultCell.HasBorder(Rectangle.LEFT_BORDER);
//table.TotalWidth = tablePosition[3]-tablePosition[1];
table.SplitRows = true;
for (int j = 0; j < 500; j++)
{
PdfPCell cell = new PdfPCell();
cell.AddElement(new Chunk(j.ToString() + "we are the champions
my friends"));
table.AddCell(cell);
}
Rectangle r = new Rectangle(PageSize.A4.GetRight(72),
PageSize.A4.GetTop(72));
column.AddElement(table);
column.Go();
while (ColumnText.HasMoreText(column.Go()))
{
numberOfPages++;
stamper.InsertPage(numberOfPages,
templateReader.GetPageSizeWithRotation(1));
column.SetSimpleColumn(tablePosition[1], tablePosition[2],
tablePosition[3], tablePosition[4] + 250, 0, Element.ALIGN_TOP);
column.Canvas = stamper.GetOverContent(numberOfPages);
// reread the fill in form and add it to our document
}
return numberOfPages;
}
private static void FillDocumentInfo(AcroFields fields)
{
// fill out invoice information
fields.SetField("DOCUMENT_TITLE", "INVOICE");
fields.SetField("COMPANY_ADDRESS", "Blah");
fields.SetField("BILLING_ADDRESS", "Blah");
fields.SetField("SHIPPING_ADDRESS", "MBlah");
fields.SetField("DETAILS", "DATE: " +
DateTime.Now.ToString("MM/DD/YYYY"));
fields.SetField("STATUS", "Completed");
fields.SetField("SHIPPING_METHOD", "UPS");
fields.SetField("PAYMENT_METHOD", "VISA x1111");
fields.SetField("SHIPPING", "Done");
}
}
--
View this message in context: http://www.nabble.com/MemoryStream-object-destroyed-by-PdfStamper.Close%28%29-tp21244882p21244882.html
Sent from the itextsharp-questions mailing list archive at Nabble.com.
------------------------------------------------------------------------------
_______________________________________________
itextsharp-questions mailing list
https://lists.sourceforge.net/lists/listinfo/itextsharp-questions
joebeazelman
2009-01-01 22:50:19 UTC
Permalink
Thanks for the reply William. I couldn't find such a method for PdfStamper,
but I did find one for its internal writer. I added the following line
after instantiating the stamper object and it didn't work:

PdfStamper stamper = new PdfStamper(templateReader,
tempStream);
stamper.Writer.CloseStream = false;

Interestingly, the code should work according to every example I've seen.
In fact, it was working at one point until I reorganized code and added
extra functionality.




Does the pdf stamper have a method indicating not to close the stream
like the pdfwriter does?

ReportOutputStream = New System.IO.MemoryStream
m_wrtReport = iTextSharp.text.pdf.PdfWriter.GetInstance(m_docReport,
ReportOutputStream)
m_wrtReport.CloseStream = False

Will Rickards
snip
--
View this message in context: http://www.nabble.com/MemoryStream-object-destroyed-by-PdfStamper.Close%28%29-tp21244882p21245658.html
Sent from the itextsharp-questions mailing list archive at Nabble.com.
joebeazelman
2009-01-14 05:26:47 UTC
Permalink
Hi Larreh,

I did find a solution to the problem. I had to do things a different way.
I did the following:

Document document = new Document();
PdfWriter writer = PdfWriter.GetInstance(document, _outputPdf);

document.Open();

MemoryStream scratchMemory = new MemoryStream();
PdfReader firstPageTemplate = new
PdfReader(@"D:\GenerateOrderPDF\GenerateOrderPDF\InvoiceFirstPageTemplate.pdf");
PdfStamper form = new PdfStamper(firstPageTemplate,
scratchMemory);

// add detailed info
AddDocumentDetails(form, order);

// add line items
AddLineItems(form, firstPageTemplate, order.Items);

// close and flatten the form
form.Writer.CloseStream = false;
form.FormFlattening = true;
form.Close();

document.Close();

You can look at my complete source code here:
http://www.nabble.com/file/p21450323/PDFOrder.cs PDFOrder.cs
I'm curious as to whether you found a solution to this issue. I've been
experiencing a similar one, albeit with PdfWriter and PdfContentByte.
PdfWriter writer = PdfWriter.GetInstance(document, new
FileStream(PDFName(TARGET_DIR, kvp.Key), FileMode.Create));
writer.CloseStream = false;
PdfContentByte ceased closing my writer, although I'm still producing
(somewhat) corrupted PDF files (the files will open, but the
pagination/background is all distorted and frequently changing pages will
produce an error; also the file size is increased by about 33%). The
interesting thing is that if I leave writer.CloseStream set to true
(default), and add a try-catch block containing "writer.Close()" the PDFs
will be created perfectly, even though writer.Close() will throw
System.ObjectDisposedException every time. However, if I comment out that
try-catch block or delete it, the PDFs will be about 66% the size and
corrupt (ie Adobe gives the following: "There was an error opening this
document. The file is damaged and could not be repaired.").
Like you, my code was previously working just fine until some
reorganization, but I can't seem to find where I've gone wrong.
Post by joebeazelman
Thanks for the reply William. I couldn't find such a method for
PdfStamper, but I did find one for its internal writer. I added the
PdfStamper stamper = new PdfStamper(templateReader, tempStream);
stamper.Writer.CloseStream = false;
Interestingly, the code should work according to every example I've seen.
In fact, it was working at one point until I reorganized code and added
extra functionality.
--
View this message in context: http://www.nabble.com/MemoryStream-object-destroyed-by-PdfStamper.Close%28%29-tp21244882p21450323.html
Sent from the itextsharp-questions mailing list archive at Nabble.com.
larreh
2009-01-14 00:57:42 UTC
Permalink
I'm curious as to whether you found a solution to this issue. I've been
experiencing a similar one, albeit with PdfWriter and PdfContentByte. After
adjusting the code like so:

PdfWriter writer = PdfWriter.GetInstance(document, new
FileStream(PDFName(TARGET_DIR, kvp.Key), FileMode.Create));
writer.CloseStream = false;

PdfContentByte ceased closing my writer, although I'm still producing
(somewhat) corrupted PDF files (the files will open, but the
pagination/background is all distorted and frequently changing pages will
produce an error; also the file size is increased by about 33%). The
interesting thing is that if I leave writer.CloseStream set to true
(default), and add a try-catch block containing "writer.Close()" the PDFs
will be created perfectly, even though writer.Close() will throw
System.ObjectDisposedException every time. However, if I comment out that
try-catch block or delete it, the PDFs will be about 66% the size and
corrupt (ie Adobe gives the following: "There was an error opening this
document. The file is damaged and could not be repaired.").

Like you, my code was previously working just fine until some
reorganization, but I can't seem to find where I've gone wrong.
Post by joebeazelman
Thanks for the reply William. I couldn't find such a method for
PdfStamper, but I did find one for its internal writer. I added the
PdfStamper stamper = new PdfStamper(templateReader, tempStream);
stamper.Writer.CloseStream = false;
Interestingly, the code should work according to every example I've seen.
In fact, it was working at one point until I reorganized code and added
extra functionality.
--
View this message in context: http://www.nabble.com/MemoryStream-object-destroyed-by-PdfStamper.Close%28%29-tp21244882p21448034.html
Sent from the itextsharp-questions mailing list archive at Nabble.com.
Paulo Soares
2009-01-15 07:46:04 UTC
Permalink
Again MemoryStream. After closing call MemoryStream.ToArray(). Don't call
GetBuffer() unless the MemoryStream is open and you also get the stream
size, GetBuffer will always return a bigger buffer than what is actlually
used. Read the .NET framework docs.

Paulo

----- Original Message -----
From: "larreh" <***@gmail.com>
To: <itextsharp-***@lists.sourceforge.net>
Sent: Wednesday, January 14, 2009 12:57 AM
Subject: Re: [itextsharp-questions] MemoryStream object destroyed by
PdfStamper.Close()



I'm curious as to whether you found a solution to this issue. I've been
experiencing a similar one, albeit with PdfWriter and PdfContentByte. After
adjusting the code like so:

PdfWriter writer = PdfWriter.GetInstance(document, new
FileStream(PDFName(TARGET_DIR, kvp.Key), FileMode.Create));
writer.CloseStream = false;

PdfContentByte ceased closing my writer, although I'm still producing
(somewhat) corrupted PDF files (the files will open, but the
pagination/background is all distorted and frequently changing pages will
produce an error; also the file size is increased by about 33%). The
interesting thing is that if I leave writer.CloseStream set to true
(default), and add a try-catch block containing "writer.Close()" the PDFs
will be created perfectly, even though writer.Close() will throw
System.ObjectDisposedException every time. However, if I comment out that
try-catch block or delete it, the PDFs will be about 66% the size and
corrupt (ie Adobe gives the following: "There was an error opening this
document. The file is damaged and could not be repaired.").

Like you, my code was previously working just fine until some
reorganization, but I can't seem to find where I've gone wrong.
Post by joebeazelman
Thanks for the reply William. I couldn't find such a method for
PdfStamper, but I did find one for its internal writer. I added the
PdfStamper stamper = new PdfStamper(templateReader, tempStream);
stamper.Writer.CloseStream = false;
Interestingly, the code should work according to every example I've seen.
In fact, it was working at one point until I reorganized code and added
extra functionality.
--
View this message in context:
http://www.nabble.com/MemoryStream-object-destroyed-by-PdfStamper.Close%28%29-tp21244882p21448034.html
Sent from the itextsharp-questions mailing list archive at Nabble.com.
Loading...