.NET Core 6使用iText7生成PDF遇Swagger异常求排查
.NET Core 6 + iText7 PDF生成异常排查
我正在使用.NET Core 6,通过iText7 NuGet库创建PDF文档,但在Swagger中得到异常响应。以下是生成PDF的CreateInvoiceDocument方法代码,以及API接口GetInvoicePDF的代码,请帮忙排查操作有误的地方。
原生成PDF方法代码
private static byte[] CreateInvoiceDocument() { using var memoryStream = new MemoryStream(); var writer = new PdfWriter(memoryStream); var pdf = new PdfDocument(writer); pdf.SetDefaultPageSize(PageSize.A4); var document = new Document(pdf); // Header table var headerTable = new Table(1); headerTable.SetWidth(UnitValue.CreatePercentValue(100)); var test = new Paragraph("dwawwa"); var headerCell = new Cell().Add(new Paragraph("Invoice")); headerCell.SetTextAlignment(TextAlignment.CENTER); headerTable.AddCell(headerCell); document.Add(headerTable); // Invoice details table var detailsTable = new Table(2); detailsTable.SetWidth(UnitValue.CreatePercentValue(100)); detailsTable.SetMarginTop(20); detailsTable.AddCell("Invoice Number"); detailsTable.AddCell("12"); detailsTable.AddCell("Date"); detailsTable.AddCell(DateTime.Now.ToString("dd/MM/yyyy")); // Add more details as needed document.Add(detailsTable); // Footer var footerTable = new Table(1); footerTable.SetWidth(UnitValue.CreatePercentValue(100)); footerTable.SetMarginTop(20); var footerCell = new Cell().Add(new Paragraph("Thank you for your business!")); footerCell.SetTextAlignment(TextAlignment.CENTER); footerTable.AddCell(footerCell); document.Add(footerTable); document.Close(); return memoryStream.ToArray(); }
原API接口代码
public async Task<IActionResult> GetInvoicePDF() { var response = CreateInvoiceDocument(); if (response == null) return BadRequest("Failed to generate the PDF."); var stream = new MemoryStream(response); return new FileStreamResult(stream, "application/pdf"); }
问题排查与修正方案
核心问题点
- iText资源未正确释放:
PdfWriter、PdfDocument、Document未使用using语句包裹,可能导致资源泄漏,生成的PDF字节流不完整,引发Swagger解析异常。 - 接口冗余异步声明:
GetInvoicePDF标记为async但无实际异步操作,不符合规范。 - 错误处理缺失:未捕获生成PDF过程中的异常,无法定位具体错误原因。
修正后的代码
修正的PDF生成方法
private static byte[] CreateInvoiceDocument() { using var memoryStream = new MemoryStream(); // 用using包裹所有iText核心对象,确保资源自动释放 using var writer = new PdfWriter(memoryStream); using var pdf = new PdfDocument(writer); using var document = new Document(pdf); pdf.SetDefaultPageSize(PageSize.A4); // Header table var headerTable = new Table(1); headerTable.SetWidth(UnitValue.CreatePercentValue(100)); var headerCell = new Cell().Add(new Paragraph("Invoice")); headerCell.SetTextAlignment(TextAlignment.CENTER); headerTable.AddCell(headerCell); document.Add(headerTable); // Invoice details table var detailsTable = new Table(2); detailsTable.SetWidth(UnitValue.CreatePercentValue(100)); detailsTable.SetMarginTop(20); detailsTable.AddCell("Invoice Number"); detailsTable.AddCell("12"); detailsTable.AddCell("Date"); detailsTable.AddCell(DateTime.Now.ToString("dd/MM/yyyy")); document.Add(detailsTable); // Footer var footerTable = new Table(1); footerTable.SetWidth(UnitValue.CreatePercentValue(100)); footerTable.SetMarginTop(20); var footerCell = new Cell().Add(new Paragraph("Thank you for your business!")); footerCell.SetTextAlignment(TextAlignment.CENTER); footerTable.AddCell(footerCell); document.Add(footerTable); // 重置流位置到起始处(ToArray不受影响,但属于良好编码习惯) memoryStream.Position = 0; return memoryStream.ToArray(); }
修正的API接口
public IActionResult GetInvoicePDF() { try { var pdfBytes = CreateInvoiceDocument(); // 使用File方法直接返回字节数组,简化代码并指定下载文件名 return File(pdfBytes, "application/pdf", $"Invoice_{DateTime.Now:yyyyMMdd}.pdf"); } catch (Exception ex) { // 捕获异常并返回具体错误信息,便于排查 return BadRequest($"生成PDF失败:{ex.Message}"); } }
修正说明
- 用
using包裹iText核心对象,确保文档资源被正确释放,避免生成损坏的PDF文件。 - 移除冗余的
async声明,使接口逻辑更清晰。 - 添加异常捕获,返回具体错误信息,快速定位问题。
- 使用
File方法直接返回字节数组,比FileStreamResult更简洁,同时设置文件名提升用户体验。
内容的提问来源于stack exchange,提问作者Svinjica
相关产品推荐
相关产品推荐

