无需第三方库,用MemoryStream生成PDF返回浏览器时损坏如何解决?
问题解决说明
根本原因
你当前代码生成的文件不是合法PDF,自然会提示损坏:PDF是有严格结构化格式规范的二进制文件,并非直接写入纯文本内容就能被识别,这是核心问题。
原代码存在的错误点
- 未按照PDF规范编写固定的文件头、对象结构、交叉引用表、文件尾等必要结构,直接写入纯文本内容
- 使用
Unicode编码写入内容,PDF基础结构默认使用ASCII编码 - 缺少PDF渲染文本所需的字体、页面参数等必要配置
无第三方库实现方案
你可以手动拼接最小规范的PDF结构,以下是可直接运行的修正代码:
// 拼接最小合法PDF结构 var pdfBuilder = new StringBuilder(); // PDF版本头 pdfBuilder.AppendLine("%PDF-1.4"); // 对象1:Catalog pdfBuilder.AppendLine("1 0 obj"); pdfBuilder.AppendLine("<</Type /Catalog /Pages 2 0 R>>"); pdfBuilder.AppendLine("endobj"); // 对象2:页面集合 pdfBuilder.AppendLine("2 0 obj"); pdfBuilder.AppendLine("<</Type /Pages /Kids [3 0 R] /Count 1>>"); pdfBuilder.AppendLine("endobj"); // 对象3:单页配置 pdfBuilder.AppendLine("3 0 obj"); pdfBuilder.AppendLine("<</Type /Page /Parent 2 0 R /MediaBox [0 0 595 842] /Contents 4 0 R /Resources <</Font <</F1 5 0 R>>>>>>"); pdfBuilder.AppendLine("endobj"); // 对象4:页面内容流(写文本的逻辑在这里) pdfBuilder.AppendLine("4 0 obj"); pdfBuilder.AppendLine("<</Length 44>>"); pdfBuilder.AppendLine("stream"); pdfBuilder.AppendLine("BT /F1 24 Tf 100 700 Td (test message) Tj ET"); pdfBuilder.AppendLine("endstream"); pdfBuilder.AppendLine("endobj"); // 对象5:字体配置 pdfBuilder.AppendLine("5 0 obj"); pdfBuilder.AppendLine("<</Type /Font /Subtype /Type1 /BaseFont /Helvetica>>"); pdfBuilder.AppendLine("endobj"); // 交叉引用表 pdfBuilder.AppendLine("xref"); pdfBuilder.AppendLine("0 6"); pdfBuilder.AppendLine("0000000000 65535 f "); pdfBuilder.AppendLine("0000000010 00000 n "); pdfBuilder.AppendLine("0000000079 00000 n "); pdfBuilder.AppendLine("0000000173 00000 n "); pdfBuilder.AppendLine("0000000301 00000 n "); pdfBuilder.AppendLine("0000000416 00000 n "); // Trailer pdfBuilder.AppendLine("trailer"); pdfBuilder.AppendLine("<</Size 6 /Root 1 0 R>>"); pdfBuilder.AppendLine("startxref"); pdfBuilder.AppendLine("492"); pdfBuilder.AppendLine("%%EOF"); // 转字节数组用ASCII编码 byte[] pdfBytes = Encoding.ASCII.GetBytes(pdfBuilder.ToString()); // 返回给浏览器 Response.AddHeader("Content-Disposition", "attachment;filename=" + id.ToString() + ".pdf"); return File(pdfBytes, "application/pdf");
代码说明
- 上面的PDF结构是符合PDF 1.4规范的最小可运行结构,已经内置了Helvetica字体和文本渲染参数,你要修改文本直接替换
(test message)里的内容即可 - 如果你需要调整字体大小、文本位置,修改
BT /F1 24 Tf 100 700 Td部分的参数即可:24是字号,100 700是页面左下角为原点的坐标值
内容的提问来源于stack exchange,提问作者SSD
相关产品推荐
相关产品推荐

