使用iText向PDF添加文本部分页面不可见的问题求助
问题:iText添加的日期戳可选中但部分页面不显示
我用iText编写了如下函数,用于给包含多张工程图纸的PDF每页右侧添加旋转后的日期戳:
Action<string, string> InsertDateStamp = (newFile, sourcePdfPath) => { string dateStamp = DateTime.Now.ToString("dd-MMM-yyyy"); using (var pdfReader = new iText.Kernel.Pdf.PdfReader(sourcePdfPath)) using (var pdfWriter = new iText.Kernel.Pdf.PdfWriter(newFile)) using (var pdfDoc = new iText.Kernel.Pdf.PdfDocument(pdfReader, pdfWriter)) { var numPages = pdfDoc.GetNumberOfPages(); for (int pageNum = 1; pageNum <= numPages; pageNum++) { var page = pdfDoc.GetPage(pageNum); var pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdfDoc); var canvas = new iText.Layout.Canvas(pdfCanvas, page.GetPageSize()); canvas.SetFontColor(iText.Kernel.Colors.ColorConstants.BLACK); canvas.SetFontSize(14); canvas.SetFont(iText.Kernel.Font.PdfFontFactory.CreateFont(iText.IO.Font.Constants.StandardFonts.TIMES_ROMAN)); canvas.ShowTextAligned(new iText.Layout.Element.Paragraph(dateStamp), 785, 300, pageNum, iText.Layout.Properties.TextAlignment.CENTER, iText.Layout.Properties.VerticalAlignment.MIDDLE, 1.5708f); pdfCanvas.Release(); } pdfDoc.Close(); pdfReader.Close(); pdfWriter.Close(); } };
多数情况下代码运行正常,但部分页面中添加的日期戳虽然可以选中复制,却无法在页面上显示(表现为文本存在但视觉上不可见)。
问题原因
核心问题是内容层级错误:你使用page.NewContentStreamBefore()将日期戳内容添加到了页面原有内容的底层,如果原有工程图纸页面存在不透明的背景或覆盖层(比如白色底色、矢量图形层),新添加的文本就会被上层内容完全遮挡,导致视觉上不可见,但文本的PDF对象确实存在,所以能被选中复制。
解决方案
把内容流从NewContentStreamBefore()改为NewContentStreamAfter(),让日期戳绘制在原有页面内容的上层,避免被遮挡:
Action<string, string> InsertDateStamp = (newFile, sourcePdfPath) => { string dateStamp = DateTime.Now.ToString("dd-MMM-yyyy"); // 提前创建字体,避免循环内重复创建 var timesFont = iText.Kernel.Font.PdfFontFactory.CreateFont(iText.IO.Font.Constants.StandardFonts.TIMES_ROMAN); using (var pdfReader = new iText.Kernel.Pdf.PdfReader(sourcePdfPath)) using (var pdfWriter = new iText.Kernel.Pdf.PdfWriter(newFile)) using (var pdfDoc = new iText.Kernel.Pdf.PdfDocument(pdfReader, pdfWriter)) { var numPages = pdfDoc.GetNumberOfPages(); for (int pageNum = 1; pageNum <= numPages; pageNum++) { var page = pdfDoc.GetPage(pageNum); // 使用NewContentStreamAfter将内容加到上层 var pdfCanvas = new PdfCanvas(page.NewContentStreamAfter(), page.GetResources(), pdfDoc); var canvas = new iText.Layout.Canvas(pdfCanvas, page.GetPageSize()); canvas.SetFontColor(iText.Kernel.Colors.ColorConstants.BLACK); canvas.SetFontSize(14); canvas.SetFont(timesFont); canvas.ShowTextAligned(new iText.Layout.Element.Paragraph(dateStamp), 785, 300, pageNum, iText.Layout.Properties.TextAlignment.CENTER, iText.Layout.Properties.VerticalAlignment.MIDDLE, 1.5708f); pdfCanvas.Release(); } // using语句会自动释放资源,无需手动Close } };
额外优化点:
- 字体对象提前在循环外创建,避免重复初始化提升性能;
- 移除
pdfDoc.Close()等手动关闭操作,using语句会自动处理资源释放,防止潜在的资源泄漏。
内容的提问来源于stack exchange,提问作者Drunken Code Monkey
相关产品推荐
相关产品推荐

