ASP.NET Core 6使用iTextSharp创建空白PDF并逐页插入图片问题
核心问题
你现有代码无法运行的直接原因:
- 传入
PdfReader的MemoryStream是未写入任何内容的空流,不包含有效PDF结构,初始化和后续PdfStamper操作必然失败,你写的inputStream.Seek(0, SeekOrigin.Begin)没有任何作用,因为流内本身无数据。 - 你不需要通过「空PDF+PdfStamper」的迂回逻辑实现需求,直接从零生成单页PDF后合并的方案更稳定,完全可以绕开这个报错。
可运行实现代码
以下代码适配ASP.NET Core 6.0环境,实现图片逐页生成PDF、插入指定文本、按位置放图片的需求,使用前请先通过NuGet安装iTextSharp依赖。
主入口方法
负责遍历图片列表、合并所有单页PDF为最终文件:
using iTextSharp.text; using iTextSharp.text.pdf; using Microsoft.Extensions.Configuration; using System.IO; using System.Collections.Generic; public static string GenerateMultiPagePdf(string docname, List<string> imagePathList, string mediaFieldContent) { var config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); var webRootPath = config["AppSettings:urunResimPath"].ToString(); var outputDir = Path.Combine(webRootPath, "menupdf"); if (!Directory.Exists(outputDir)) Directory.CreateDirectory(outputDir); var outputFullPath = Path.Combine(outputDir, $"{docname}.pdf"); using (var outputStream = new FileStream(outputFullPath, FileMode.Create, FileAccess.Write)) { var pdfMerger = new PdfConcatenate(outputStream); foreach (var imgRelativePath in imagePathList) { var singlePageBytes = BuildSinglePagePdf(imgRelativePath, mediaFieldContent, webRootPath); using (var pageReader = new PdfReader(singlePageBytes)) { pdfMerger.AddPages(pageReader); } } pdfMerger.Close(); } return outputFullPath; }
单页PDF生成方法
负责单张图片+对应文本生成单页PDF字节,不需要依赖提前准备的PDF模板:
private static byte[] BuildSinglePagePdf(string imgRelativePath, string mediaText, string webRootPath) { var imgFullPath = Path.Combine(webRootPath, "barkod-menu", imgRelativePath); var targetImage = Image.GetInstance(imgFullPath); using (var ms = new MemoryStream()) { // 页面大小匹配图片尺寸,需要固定A4的话替换为PageSize.A4即可 var doc = new Document(targetImage, 0, 0, 0, 0); var writer = PdfWriter.GetInstance(doc, ms); doc.Open(); // 写入MediaField对应文本,坐标、字体、字号可根据你的需求调整 var canvas = writer.DirectContent; // 若不需要显示中文,可替换字体为Helvetica,避免字体路径依赖 var baseFont = BaseFont.CreateFont(@"C:\Windows\Fonts\msyh.ttc,0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); canvas.BeginText(); canvas.SetFontAndSize(baseFont, 12); // 坐标原点在页面左下角,示例位置为页面顶部左侧,可自行调整数值匹配你的示意图布局 canvas.ShowTextAligned(Element.ALIGN_LEFT, mediaText, 20, doc.PageSize.Height - 30, 0); canvas.EndText(); // 放置图片:预留顶部文本区域,图片自适应大小居中 targetImage.ScaleToFit(doc.PageSize.Width, doc.PageSize.Height - 50); targetImage.SetAbsolutePosition( (doc.PageSize.Width - targetImage.ScaledWidth) / 2, (doc.PageSize.Height - 50 - targetImage.ScaledHeight) / 2 ); doc.Add(targetImage); doc.Close(); writer.Close(); return ms.ToArray(); } }
调整说明
- 文本坐标、图片边距、字体大小可以根据你需要的布局修改数值,和参考示意图对齐即可。
- 所有流均通过
using自动释放,不会出现文件占用问题。 - 路径统一使用
Path.Combine拼接,兼容Windows和Linux部署环境。 - 如果你必须使用带预设表单域的PDF模板,只需要把模板文件的读取流传入
PdfReader,替换掉空流即可正常使用PdfStamper填充域、插入图片。

内容的提问来源于stack exchange,提问作者btest
相关产品推荐
相关产品推荐

