【问题标题】:Can't add footer to some pdf in itextsharp无法在 itextsharp 中为某些 pdf 添加页脚
【发布时间】:2018-03-08 03:43:36
【问题描述】:

我正在使用 itextsharp。我可以为某些 pdf 添加页脚,但有些我不能。这是我的代码:

byte[] bytes = File.ReadAllBytes(PPTpath);
Font blackFont = FontFactory.GetFont("Arial", 12, Font.NORMAL, BaseColor.BLACK);
using (MemoryStream stream = new MemoryStream())
{
    PdfReader reader = new PdfReader(bytes);
    using (stamper = new PdfStamper(reader, stream))
    {
        //stamper.FormFlattening = true;
        int pages = reader.NumberOfPages;
        for (int i = 1; i <= pages; i++)
        {
            //ColumnText.ShowTextAligned(stamper.GetUnderContent(i), Element.ALIGN_RIGHT, new Phrase("Generated ECAB", blackFont), 568f, 15f, 0);
            ColumnText.ShowTextAligned(stamper.GetOverContent(i), Element.ALIGN_RIGHT, new Phrase("Generated ECAB", blackFont), 568f, 15f, 0);
        }
    }
    bytes = stream.ToArray();
    stamper.Close();
}
File.WriteAllBytes(PPTpath, bytes);

这是我尝试添加页脚https://dl.ubnt.com/datasheets/airfiber/airFiber_DS.pdf 的pdf 链接。有人可以解释为什么我不能在这个 pdf 文件中添加页脚。谢谢

【问题讨论】:

  • 稍后我会详细查看,但一个明显的可能原因是您在ColumnText.ShowTextAligned 中使用了固定坐标。因此,您需要一个固定的坐标系。另一方面,PDF 在每一页上可以有不同的坐标系,只是原点通常在左下角。
  • @mkl ok 先生,我如何获得动态坐标?
  • 我按原样运行您的代码(只是将结果写入不同的文件),它开箱即用,添加了页脚!您可能只是没有权限覆盖该文件吗?您使用哪个 iTextSharp 版本?我显然使用的是最新的 5.5.x:5.5.13。

标签: c# itext


【解决方案1】:

正如评论中已经提到的,有问题的代码适用于共享 PDF,唯一的区别是我为结果使用了不同的文件,并且我声明了变量 stamper。因此,可能不允许 OP 覆盖有问题的文件。

话虽如此,代码中确实存在问题,有时可能会或可能不会导致问题:

假设坐标系

OP 在绘制页脚时使用固定坐标:

ColumnText.ShowTextAligned(stamper.GetOverContent(i), Element.ALIGN_RIGHT,
    new Phrase("Generated ECAB", blackFont), 568f, 15f, 0);

只要页面具有像 LETTER 或 A4 这样的宽度,这很有效,但对于较小的纸张格式,字符串可能会被截断。

此外,这些坐标假定坐标系的原点位于可见页面的左下角。虽然这种情况经常发生,但并非必须如此。每个页面都可以定义自己的底层内容画布可见窗口。

关于这两个潜在问题,您可以通过根据页面裁剪框值计算坐标来解决:

Rectangle cropBox = reader.GetCropBox(i);
ColumnText.ShowTextAligned(stamper.GetOverContent(i), Element.ALIGN_RIGHT,
    new Phrase("Generated ECAB", blackFont), cropBox.GetRight(44f), cropBox.GetBottom(15f), 0);

这会将文本的锚点放置在纸张右侧边框左侧 44 个单位和底部边框上方 15 个单位处。

此外,还有一个小怪:

使用块后关闭压模

OP 在using 之外定义stamper,然后将其关闭。

首先,using 块的末尾已经自动关闭了stamper,因此此后再次关闭它充其量是无操作。因此,OP 应该删除 Close 调用。

此外,尚不清楚 OP 在何处声明了 stamper 变量。如果他例如将其定义为类成员,如果从多个线程中使用该类,他可能会遇到问题;由于stamper 是在using 的开头创建并在using 块的末尾设置的,我建议在using 中声明它,即:

using (MemoryStream stream = new MemoryStream())
{
    PdfReader reader = new PdfReader(bytes);
    using (PdfStamper stamper = new PdfStamper(reader, stream))
    {
        //stamper.FormFlattening = true;
        int pages = reader.NumberOfPages;
        for (int i = 1; i <= pages; i++)
        {
            Rectangle cropBox = reader.GetCropBox(i);
            ColumnText.ShowTextAligned(stamper.GetOverContent(i), Element.ALIGN_RIGHT,
                new Phrase("Generated ECAB", blackFont), cropBox.GetRight(44f), cropBox.GetBottom(15f), 0);
        }
    }
    bytes = stream.ToArray();
}

【讨论】:

    猜你喜欢
    • 2020-07-23
    • 2013-09-30
    • 1970-01-01
    • 2018-05-25
    • 2012-05-17
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多