C# 使用iText7修改PDF并保存到Blob Storage的实现问题
问题原因排查
- 第一个常见问题:从Blob存储获取的
pdfTemplate流位置不在起始点,导致PdfReader读取不到有效PDF内容,最终生成的文件只有基础头信息,所以长度只有十几字节。你需要在初始化PdfReader前先把输入流的Position重置为0。 - 第二个常见问题:iText7的
PdfWriter默认在PdfDocument关闭时会同步关闭关联的输出流,部分情况下会导致流内容未完全写入就被截断。你可以显式配置PdfWriter的关闭行为避免这个问题。
修正后的完整代码
IDictionary<string, PdfFormField> fields; using MemoryStream outStream = new MemoryStream(); // 1. 从Blob获取模板流 var pdfTemplate = _blobStorageService.GetBlob("mycontainer", "TestPDF.pdf"); // 2. 重置输入流位置到起始点,避免读取空内容 if (pdfTemplate.CanSeek) { pdfTemplate.Position = 0; } // 3. 配置PdfWriter,设置不自动关闭输出流 var writerProperties = new WriterProperties() .SetCloseStream(false); // 避免PdfDocument关闭时自动释放outStream PdfReader reader = new PdfReader(pdfTemplate); PdfWriter writer = new PdfWriter(outStream, writerProperties); PdfDocument pdfDoc = new PdfDocument(reader, writer); PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDoc, true); fields = form.GetFormFields(); if (fields.TryGetValue("header", out PdfFormField cl)) { cl.SetValue("This is a header"); // 如果不需要后续再编辑表单,可以加这行展平,减小文件体积同时避免表单字段丢失 // form.FlattenFields(); } // 关闭文档,触发内容写入 pdfDoc.Close(); reader.Close(); writer.Close(); // 4. 重置输出流位置到起始点,准备上传 outStream.Position = 0; // 5. 直接传outStream作为上传参数即可,大部分Blob存储的Upload方法都支持Stream类型输入 // 如果你的UploadBlobAsync只接受字节数组,就传outStream.ToArray() await _blobStorageService.UploadBlobAsync("mycontainer", outStream, "newpdf.pdf"); // 字节数组上传写法参考: // await _blobStorageService.UploadBlobAsync("mycontainer", outStream.ToArray(), "newpdf.pdf");
补充验证步骤
如果修改后输出流长度还是不对,可以先把pdfTemplate流复制到本地文件,确认从Blob读取的模板PDF本身是完好可打开的,排除读取环节的问题。
内容的提问来源于stack exchange,提问作者JerseyDuke
相关产品推荐
相关产品推荐

