You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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
    }
};

额外优化点:

  1. 字体对象提前在循环外创建,避免重复初始化提升性能;
  2. 移除pdfDoc.Close()等手动关闭操作,using语句会自动处理资源释放,防止潜在的资源泄漏。

内容的提问来源于stack exchange,提问作者Drunken Code Monkey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 09:13:11