C# 如何将MemoryStream中的PDF文件保存到指定文件夹
将MemoryStream中生成的PDF保存到本地文件夹的实现方案
你当前代码已经完成了PDF生成、流位置重置的核心步骤,只需要将流内的二进制内容写入本地文件即可,同时需要修正原代码中遗漏的文档打开步骤,否则生成的PDF会是空白损坏状态。
核心实现步骤
- 补全iTextSharp文档操作的必要逻辑:创建PdfWriter后必须调用
document.Open()才能写入内容 - 校验目标保存路径的目录是否存在,不存在则提前创建,避免路径不存在抛出异常
- 读取MemoryStream中的PDF二进制内容,写入本地目标文件
- 操作完成后正确释放所有流和文档对象,避免资源泄漏
完整可运行代码
using System.IO; using iTextSharp.text; using iTextSharp.text.pdf; // 原有业务逻辑 string beneficiarioRelatorio = service.RelatorioBeneficiarioService(numeroProtocolo); string matriculaRelatorio = service.RelatorioMatriculaService(numeroProtocolo); Document document = new Document(PageSize.A4, 30f, 20f, 50f, 40f); MemoryStream stream = new MemoryStream(); try { PdfWriter pdfWriter = PdfWriter.GetInstance(document, stream); // 保持MemoryStream在PdfWriter关闭后不被释放,方便后续读取内容存文件 pdfWriter.CloseStream = false; // 原代码遗漏:必须调用Open()才能向文档添加内容 document.Open(); Paragraph titulo = new Paragraph("Comprovante de solicitação de serviço eletrônico", fontTextBold); titulo.Alignment = Element.ALIGN_CENTER; titulo.SpacingBefore = 50; titulo.IndentationLeft = 65; document.Add(titulo); // 其余需要添加的PDF内容统一放在此处 } catch (DocumentException de) { Console.Error.WriteLine(de.Message); } catch (IOException ioe) { Console.Error.WriteLine(ioe.Message); } finally { // 确保文档被正确关闭,完成PDF内容写入流 if (document.IsOpen()) { document.Close(); } } stream.Flush(); // 将流指针重置到起始位置,才能读取完整内容 stream.Position = 0; // --------------- // 本地保存核心逻辑 // --------------- // 替换为实际要保存的完整路径(文件夹+文件名) string saveFullPath = @"D:\PDF存储目录\Relatorio_Solicitacao_Servico_Eletronico.pdf"; // 提取目录路径,不存在则创建 string? targetDir = Path.GetDirectoryName(saveFullPath); if (!string.IsNullOrEmpty(targetDir) && !Directory.Exists(targetDir)) { Directory.CreateDirectory(targetDir); } // 写法1:直接写入字节数组,适合中小体积PDF,代码简洁 byte[] pdfContent = stream.ToArray(); File.WriteAllBytes(saveFullPath, pdfContent); // 写法2:流拷贝方式,适合大体积PDF,内存占用更低 // using (FileStream fileStream = new FileStream(saveFullPath, FileMode.Create, FileAccess.Write)) // { // stream.CopyTo(fileStream); // } // 释放MemoryStream资源 stream.Dispose();
注意事项
document.Close()必须在所有内容添加完成后调用,该方法会完成PDF的元数据写入、内容收尾,否则生成的PDF文件会损坏- 路径字符串推荐用
@前缀的原义字符串,避免转义字符导致路径识别错误 - 如果是Web项目,要确保运行程序的账号对目标保存文件夹有写入权限,否则会抛出权限不足的异常
- 你注释掉的
return File()是Web接口直接返回文件流给前端下载的写法,和本地保存逻辑互不冲突,按需选择即可
内容的提问来源于stack exchange,提问作者José Eronaldo
相关产品推荐
相关产品推荐

