ASP.NET Core MVC导出PDF报错:无法加载PDF文档求解决方案
数据库数据导出PDF后无法加载的问题排查与解决
编写了将数据库表数据导出为PDF的C#代码,代码可正常执行,但下载生成的PDF文件时出现报错:
Error - failed to load PDF document
相关代码
私有方法getexportdata
private void getexportdata() { try { string sql = null; if (role == "BLC") { sql = "select SurveyInformationId,AreaName,userinfo.EmployeeName,BranchName,SurveyDate,ManagerApprove,u.EmployeeName as manager from SurveyInformation inner join Branch on Branch.BranchId = SurveyInformation.BranchId inner join UserInfo on UserInfo.UserId = SurveyInformation.CreatedBy inner join UserInfo u on u.UserId = SurveyInformation.ManagerApproveid where ManagerApprove = 'Approve' or CSRApprove = 'Pending'"; } if (role == "Admin") { sql = "select SurveyInformationId,AreaName,userinfo.EmployeeName,BranchName,SurveyDate,ManagerApprove,u.EmployeeName as manager from SurveyInformation inner join Branch on Branch.BranchId = SurveyInformation.BranchId inner join UserInfo on UserInfo.UserId = SurveyInformation.CreatedBy inner join UserInfo u on u.UserId = SurveyInformation.ManagerApproveid where ManagerApprove = 'Approve' or CSRApprove = 'Pending'"; } database db = new database(); db.openconnection(); SqlCommand cmd = new SqlCommand(sql, db.cn); cmd.CommandType = CommandType.Text; cmd.Parameters.AddWithValue("@BranchId", Session["BranchId"].ToString()); //cmd.Parameters.AddWithValue("@UserId", Session["UserId"].ToString()); SqlDataAdapter da = new SqlDataAdapter(cmd); DataTable dt = new DataTable(); da.Fill(dt); db.closeconnection(); ExportToPDF(dt, "SurveyInformation Report"); } catch { } }
私有方法ExportToPDF
private void ExportToPDF(DataTable dt, string s) { try { if (dt.Rows.Count > 0) { string filename = s + DateTime.Now.ToString(" dd-MM-yyyy hh:mm:ss") + ".pdf"; System.IO.StringWriter tw = new System.IO.StringWriter(); System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw); DataGrid dgGrid = new DataGrid(); dgGrid.DataSource = dt; dgGrid.DataBind(); //Get the HTML for the control. dgGrid.RenderControl(hw); //Write the HTML back to the browser. Response.ContentType = "application/pdf"; Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename + ""); //Response.AppendHeader("Content-Disposition", "inline; filename=" + filename + ".pdf"); this.EnableViewState = false; Response.Write(tw.ToString()); Response.End(); Response.Close(); Response.Flush(); this.Page.ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('Report Export Succesfully')", true); } else { this.Page.ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('No Data to Export')", true); } } catch { } }
受保护方法btexportblc_Click
protected void btexportblc_Click(object sender, EventArgs e) { getexportdata(); }
问题根源与修复方案
核心问题
你当前的代码根本没有生成真正的PDF文件——只是把DataGrid渲染出的HTML文本,强行设置了application/pdf的Content-Type响应头。浏览器收到的是HTML内容,却被标记为PDF格式,自然无法解析加载。
修复步骤
1. 替换HTML输出为真实PDF生成逻辑
需要使用专门的PDF生成库(比如iTextSharp、IronPDF)来将数据转换为标准PDF格式。以下是基于iTextSharp(适用于.NET Framework)的修改示例:
首先安装iTextSharp NuGet包,然后改写ExportToPDF方法:
private void ExportToPDF(DataTable dt, string reportTitle) { try { if (dt.Rows.Count == 0) { Page.ClientScript.RegisterStartupScript(GetType(), "alert", "alert('No Data to Export')", true); return; } string filename = $"{reportTitle} {DateTime.Now.ToString("dd-MM-yyyy hh:mm:ss")}.pdf"; using (MemoryStream ms = new MemoryStream()) { // 创建PDF文档实例 Document document = new Document(PageSize.A4, 25, 25, 30, 30); PdfWriter writer = PdfWriter.GetInstance(document, ms); document.Open(); // 添加报表标题 Paragraph title = new Paragraph(reportTitle, new Font(Font.FontFamily.TIMES_ROMAN, 16, Font.BOLD)); title.Alignment = Element.ALIGN_CENTER; document.Add(title); document.Add(new Paragraph("\n")); // 创建PDF表格,列数与DataTable一致 PdfPTable table = new PdfPTable(dt.Columns.Count); table.WidthPercentage = 100; // 添加表头 foreach (DataColumn col in dt.Columns) { PdfPCell cell = new PdfPCell(new Phrase(col.ColumnName, new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.BOLD))); cell.BackgroundColor = new BaseColor(240, 240, 240); table.AddCell(cell); } // 添加表格数据行 foreach (DataRow row in dt.Rows) { foreach (var item in row.ItemArray) { table.AddCell(new Phrase(item.ToString(), new Font(Font.FontFamily.TIMES_ROMAN, 12))); } } document.Add(table); document.Close(); // 将生成的PDF输出到响应流 Response.Clear(); Response.ContentType = "application/pdf"; Response.AppendHeader("Content-Disposition", $"attachment; filename={filename}"); Response.BinaryWrite(ms.ToArray()); Response.End(); } } catch (Exception ex) { // 添加异常提示,方便排查问题 Page.ClientScript.RegisterStartupScript(GetType(), "alert", $"alert('Export failed: {ex.Message}')", true); } }
2. 修复其他潜在问题
- SQL冗余优化:
role == "BLC"和role == "Admin"的SQL语句完全一致,可以合并为一个判断,减少冗余代码。 - 异常处理补全:原代码的
catch块为空,建议添加日志记录或错误提示,避免问题无法追踪。 - 参数化查询修正:原SQL语句中未使用
@BranchId参数,却添加了该参数,会导致SQL执行报错,需在WHERE子句中补充AND Branch.BranchId = @BranchId。 - 响应逻辑修正:原代码中
Response.End()之后的Response.Close()、Response.Flush()和脚本注册代码都不会执行,因为Response.End()会直接终止响应流程。
内容的提问来源于stack exchange,提问作者Adnan Attar
相关产品推荐
相关产品推荐

