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

使用iTextSharp在PDF指定位置添加文本时原有内容丢失的解决求助

解决iTextSharp添加文本后PDF原有内容丢失的问题

看起来你踩了iTextSharp入门时的常见坑——你的代码其实是在新建一个PDF文档,然后只导入了原PDF的第一页,还因为写入顺序的问题,导致原内容被覆盖(或者说根本没正确保留)。别担心,用PdfStamper就能完美解决这个问题,它是iTextSharp专门用来修改现有PDF的工具,能完整保留原文档的所有页面和内容,同时让你添加新元素。

问题根源

你当前的写法存在几个核心问题:

  1. 用FileMode.Open + FileAccess.Write打开原文件时,会直接清空原有内容
  2. 手动导入单页,丢失了原PDF的其他页面
  3. 添加文本后再导入页面,相当于把原页面盖在了文本上面(即使顺序对,也只保留了一页)

修正后的代码

下面是完整的修复版本,我标注了关键改动:

// 读取原PDF文件
PdfReader reader = new PdfReader(FileUpload1.PostedFile.FileName);

// 建议先写入临时文件,避免操作失败损坏原文件
string tempFilePath = Path.GetTempFileName();

try
{
    using (FileStream fs = new FileStream(tempFilePath, FileMode.Create))
    {
        // 核心替换:用PdfStamper替代PdfWriter+Document,它会自动保留原PDF的所有内容
        using (PdfStamper stamper = new PdfStamper(reader, fs))
        {
            // 获取第一页的内容层:GetOverContent表示在原有内容上方添加文本
            // 如果要在原内容下方添加,改用GetUnderContent(1)
            PdfContentByte cb = stamper.GetOverContent(1);

            // 设置字体和颜色(和你原来的代码一致)
            BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            cb.SetColorFill(BaseColor.DarkGray);
            cb.SetFontAndSize(bf, 8);

            // 重置文件流位置(避免因为之前读取过导致哈希计算错误)
            FileUpload1.PostedFile.InputStream.Position = 0;
            byte[] data = ReadFully(FileUpload1.PostedFile.InputStream);
            
            // 计算哈希值(和你原来的代码一致)
            string hash = string.Empty;
            using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
            {
                hash = Convert.ToBase64String(sha1.ComputeHash(data));
            }

            // 添加文本到指定坐标(用常量替代数字更清晰)
            cb.BeginText();
            cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT, hash, 400, 150, 0);
            cb.EndText();
        }
    }

    // 替换原文件(操作成功后执行)
    string originalFilePath = Path.GetFullPath(FileUpload1.PostedFile.FileName);
    File.Delete(originalFilePath);
    File.Move(tempFilePath, originalFilePath);
}
finally
{
    // 确保reader被关闭
    reader.Close();
    // 清理临时文件(如果替换原文件失败的话)
    if (File.Exists(tempFilePath))
    {
        File.Delete(tempFilePath);
    }
}

// 补充ReadFully方法实现(如果还没写的话)
private byte[] ReadFully(Stream input)
{
    using (MemoryStream ms = new MemoryStream())
    {
        input.CopyTo(ms);
        return ms.ToArray();
    }
}

关键改动说明

  • 使用PdfStamper:这是修改现有PDF的标准方式,它会自动复制原PDF的所有页面、元数据和内容,不需要手动导入页面
  • GetOverContent/GetUnderContent:精准控制新内容在原内容的上层还是下层
  • 临时文件写入:避免直接操作原文件导致意外损坏,操作成功后再替换原文件
  • 重置流位置:确保文件流从开头读取,避免哈希计算错误

这样修改后,你添加的文本会出现在原PDF第一页的指定位置,同时所有原有内容都会完整保留。

内容的提问来源于stack exchange,提问作者Sandeep Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:03:49