ここのコメントの提案に基づいて、メソッドをリファクタリングして、「使用中」の iTextSharp.text.Document の外側 (ただし、MemoryStream using 句内) の MemoryStream にデータを割り当てようとしました。
internal static HttpResponseMessage GeneratePDFOfReportFutures()
{
HttpResponseMessage result = null;
futureReports = GetAllFutureReports();
try
{
using (var ms = new MemoryStream())
{
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25)) // the "Rotate" makes it landscape orientation
{
using (PdfWriter.GetInstance(doc, ms))
{
doc.Open();
. . .
// "int i" is for testing a quick exit of this long-running loop
int i = 0;
foreach (QueuedReports qr in futureReports)
{
var tblRow = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 4f
};
float[] tblRowWidths = new float[] { 220f, 180f, 220f, 160f, 160f, 340f };
tblRow.SetWidths(tblRowWidths);
tblRow.HorizontalAlignment = Element.ALIGN_LEFT;
var phraseRptName = new Phrase(qr.ReportName, helvetica9);
var cellRptName = GetCellForBorderedTable(phraseRptName, Element.ALIGN_CENTER, BaseColor.WHITE);
cellRptName.VerticalAlignment = Element.ALIGN_MIDDLE;
tblRow.AddCell(cellRptName);
. . .
tblRow.AddCell(cellRecipients);
doc.Add(tblRow);
i++;
if (i >= 12)
{
break;
}
} // foreach
} // pdfWriter
} // doc
var bytes = ms.ToArray();
result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(bytes)
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = string.Format("{0}.pdf", "test")
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
} // memoryStream
} // try
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return result;
} // GeneratePDFOfReportFutures
「break」行にブレークポイントを指定してステップ (F10) を実行すると、バイトへの割り当てに到達する前に次の例外がキャッチされます。
System.ObjectDisposedException がキャッチされました HResult=-2146232798
Message= Cannot access a closed Stream。Source=mscorlib
ObjectName="" StackTrace: System.IO.__Error.StreamIsClosed() で System.IO. iTextSharp.text.pdf.OutputStreamCounter.Write(Byte[] バッファー、Int32 オフセット、Int32 カウント) でのMemoryStream .Write(Byte[] バッファー、Int32 オフセット、Int32 カウント) iTextSharp.text.pdf.PdfIndirectObject.WriteTo(Stream os) で) iTextSharp.text.pdf で。PdfWriter.PdfBody.Write(PdfIndirectObject 間接、Int32 refNumber、Int32 世代) at iTextSharp.text.pdf.PdfWriter.PdfBody.Add(PdfObject objecta、Int32 refNumber、Int32 世代、Boolean inObjStm) at iTextSharp.text.pdf.PdfWriter.PdfBody. Add(PdfObject objecta, PdfIndirectReference refa, Boolean inObjStm) at iTextSharp.text.pdf.PdfWriter.PdfBody.Add(PdfObject objecta, PdfIndirectReference refa) at iTextSharp.text.pdf.PdfWriter.AddToBody(PdfObject objecta, PdfIndirectReference refa) at iTextSharp. iTextSharp.text.pdf.FontDetails.WriteFont(PdfWriter ライター) の iTextSharp.text.pdf.PdfWriter.AddSharedObjectsToBody() の iTextSharp.text. iTextSharp.text の pdf.PdfWriter.Close()。DocWriter.Dispose()
PdfWriter や Doc へのアクセスが問題を引き起こしているように見えたので、ドキュメントを使用するだけでなく、pdfWriter を使用して書き込みコードを移動する必要があるように思われるので、次のようにコードを移動しました。
. . .
} // foreach
var bytes = ms.ToArray();
result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(bytes)
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = string.Format("{0}.pdf", "test")
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
} // pdfWriter
} // doc
} // memoryStream
} // try
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return result;
...しかし、私はまだまったく同じ例外を受け取ります。ただし、この行で F10 キーを押すまで例外がスローされないという点で、現在表示されているものと前回の投稿で説明されているものには違いがあります。
} // pdfWriter
次のように、リターン行を上に移動した場合 (ただし、catch ブロックの下に保持したまま):
return result;
} // pdfWriter
...「return result」行の F10ing で例外がスローされます。
これが失敗する理由と、それを防ぐ方法を教えてください。