使用 iText 自定义签名外观

2024-01-21

我正在尝试使用 iText(sharp,版本 5.5.13)创建自定义数字签名,用户可以从一组四个位置(顶部、底部、左侧和右侧)设置图像位置,如下所示:

Rigth:

Left:

Top:

Bottom:

到目前为止,我尝试在签名的第 0 层上工作,但我认为我做错了,因为签名详细信息是在第 2 层中设置的。

然而,这只是设置图像位置的初始草图。在下面的代码中,我加载图像并将其放入一个块中(想法取自此example https://stackoverflow.com/a/30844970/6248239)

PdfTemplate pdfTemplate = sap.GetLayer(0);
ColumnText c1 = new ColumnText(pdfTemplate);
Image img = Image.GetInstance(signatureImage);
Phrase elements = new Phrase();
elements.Add(new Chunk(img, 0, 0, true));
//c1.SetSimpleColumn(elements, 0, 0, rectangle.Width, rectangle.Height / 4, 0, Element.ALIGN_CENTER); // align bottom
//c1.SetSimpleColumn(elements, 0, rectangle.Height / 2, rectangle.Width, rectangle.Height, 0, Element.ALIGN_CENTER); // align top
c1.SetSimpleColumn(elements, rectangle.Width/2, 0, rectangle.Width, rectangle.Height, 0, Element.ALIGN_CENTER); // align right
//c1.SetSimpleColumn(elements, 0, 0, rectangle.Width/2, rectangle.Height, 0, Element.ALIGN_CENTER); // align left
c1.Go();

结果或多或少是预期的,但有两个问题:签名信息占据了整个矩形(这是正常的,因为我没有修改第 2 层,并且第 0 层中的图像没有按应有的比例缩放)

如果我缩放图像以适合该列,它将到达矩形的顶部:

有没有办法做到“开箱即用”,或者我需要重载构建签名外观的方法(像这样 https://stackoverflow.com/a/49009766/6248239)我怎样才能做到这一点?


我最初的音乐会不是使用 iText (v7),因为我们没有太多时间来迁移使用 iText (v5) 的所有项目,但我继续尝试使用 v7。但说实话,用 v5 似乎不太容易实现。

另一方面,在 iText (v7) 中,我可以使用这个简单的方法非常快速地完成此操作:

private static void SetCustomSignature(PdfDocument doc, PdfSignatureAppearance sap, SignatureFormat signatureFormat, X509Certificate2 signerCertificate) {
    string signatureFont = signatureFormat.Font;
    float signatureFontSize = float.Parse(signatureFormat.FontSize);
    Rectangle rect = new Rectangle(250, 100, 200, 80);
    sap.SetPageRect(rect).SetPageNumber(1);
    PdfFormXObject layer2 = sap.GetLayer2();
    PdfCanvas canvas = new PdfCanvas(layer2, doc);

    float MARGIN = 2;
    PdfFont font = PdfFontFactory.CreateFont();

    string signingText = GetSignatureInfo(signerCertificate, signatureFormat);

    // Signature at left and image at right
    //Rectangle dataRect = new Rectangle(rect.GetWidth() / 2 + MARGIN / 2, MARGIN, rect.GetWidth() / 2 - MARGIN, rect.GetHeight() - 2 * MARGIN);
    //Rectangle signatureRect = new Rectangle(MARGIN, MARGIN, rect.GetWidth() / 2 - 2 * MARGIN, rect.GetHeight() - 2 * MARGIN);

    // Signature at right and image at left
    //Rectangle dataRect = new Rectangle(MARGIN, MARGIN, rect.GetWidth() / 2 - MARGIN, rect.GetHeight() - 2 * MARGIN);
    //Rectangle signatureRect = new Rectangle(rect.GetWidth() / 2 + MARGIN / 2, MARGIN, rect.GetWidth() / 2 - 2 * MARGIN, rect.GetHeight() - 2 * MARGIN);

    // Signature at top and image at bottom
    //Rectangle dataRect      = new Rectangle(MARGIN, MARGIN, rect.GetWidth() - 2 * MARGIN, rect.GetHeight() / 2 - MARGIN);
    //Rectangle signatureRect = new Rectangle(MARGIN, rect.GetHeight() / 2 + MARGIN, rect.GetWidth() - 2 * MARGIN, rect.GetHeight() / 2 - MARGIN);

    // Signature at bottom and image at top
    Rectangle dataRect = new Rectangle(MARGIN, rect.GetHeight() / 2 + MARGIN, rect.GetWidth() - 2 * MARGIN, rect.GetHeight() / 2 - MARGIN);
    Rectangle signatureRect = new Rectangle(MARGIN, MARGIN, rect.GetWidth() - 2 * MARGIN, rect.GetHeight() / 2 - MARGIN);

    try {
        Canvas signLayoutCanvas = new Canvas(canvas, doc, signatureRect);
        Paragraph paragraph = new Paragraph(signingText).SetFont(font).SetMargin(0).SetMultipliedLeading(0.9f).SetFontSize(10);
        Div div = new Div();
        div.SetHeight(signatureRect.GetHeight());
        div.SetWidth(signatureRect.GetWidth());
        div.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE);
        div.SetHorizontalAlignment(iText.Layout.Properties.HorizontalAlignment.CENTER);
        div.Add(paragraph);
        signLayoutCanvas.Add(div);


        Canvas dataLayoutCanvas = new Canvas(canvas, doc, dataRect);
        Image image = new Image(ImageDataFactory.Create(signatureFormat.SignatureImage));
        image.SetAutoScale(true);
        Div dataDiv = new Div();
        dataDiv.SetHeight(dataRect.GetHeight());
        dataDiv.SetWidth(dataRect.GetWidth());
        dataDiv.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE);
        dataDiv.SetHorizontalAlignment(iText.Layout.Properties.HorizontalAlignment.CENTER);
        dataDiv.Add(image);
        dataLayoutCanvas.Add(dataDiv);
    }
    catch {
        throw;
    }
}

这将产生以下签名:

当然,它仍然需要一些改进,但它可以作为其他人的例子:-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 iText 自定义签名外观 的相关文章

  • 线程独占数据:如何存储和访问?

    NET 中是否有可能将对象实例绑定到线程的当前执行上下文 这样在代码的任何部分我都可以做类似的事情CurrentThread MyObjectData DoOperation 并确保我访问特定于线程的数据 谢谢 你可以看一下线程静态属性 h
  • 值类型如何实现引用类型

    我遇到了一个值类型正在实现 ref 的场景 类型 只是想知道这怎么可能 幕后发生了什么 结构体是值类型 接口是引用 类型但结构可以实现接口而不会出现任何错误 有什么想法吗 提前致谢 实际上 它同时以两种不同的方式进行 首先 任何值类型都可以
  • C 中的 '\0' 和 printf()

    在 C 入门课程中 我了解到在存储字符串时存储空字符 0在它的最后 但是如果我想打印一个字符串怎么办 printf hello 虽然我发现它并没有结束 0通过以下声明 printf d printf hello Output 5 但这似乎不
  • 带有嵌入 Flash 视频的 PDF 示例?

    有谁知道我在哪里可以查看嵌入 Flash 视频的 PDF 示例 我知道问这个问题很愚蠢 因为你会认为任何面向技术的用户都应该能够使用谷歌找到一个 但我真的找不到 我的另一个问题是 使用 C 中的 API 将 Flash 视频嵌入 PDF 文
  • C++ 并行任务的开销

    我有以下简单的功能 include
  • C 链表销毁函数

    我正在尝试学习 C 和很多人一样 我对指针有点困惑 无论如何 我创建了一个递归函数来销毁我的链表 但是正如我调试的那样 当我从函数返回时 列表的头部不应该为空 所以我猜这是对指针的一些基本误解 这是函数 void destroy struc
  • UI 线程正在阻塞调用 COM 对象的后台线程

    我正在开发一个通过第三方 COM 库与外部设备通信的应用程序 我试图让与设备的所有通信都通过后台线程 以防止通信问题搞砸我的应用程序 并消除在 UI 线程中进行通信所引入的一些其他复杂性 问题是 每当发生导致主 UI 线程阻塞的情况 即调用
  • 我如何知道向量的实际最大大小? (不使用 std::vector::max_size)

    在在线课程中 我正在学习向量 在其中一个例子中 他们解释说 std vector max size 应该给我向量可以达到的最大大小 我决定测试一下 include
  • 如何生成可变参数包?

    给定不相关的输入是否可以生成非类型参数包 我的意思是 我想改变这一点 template
  • 为什么我收到编译错误“使用已删除的函数 'std::unique_ptr ...”

    我收到一条巨大的编译错误消息 c mingw include c 6 1 0 bits predefined ops h 123 18 error use of deleted function std unique ptr lt Tp D
  • 是否自初始化 'A a = a;'允许吗?

    此代码在运行时在复制构造函数中失败 但编译器 MSVS2008 没有发出警告 您能解释一下 最好引用标准 这段代码是否非法或什么 我理解 A a a 永远不应该写在第一位 但我正在寻找理论背景 class A public A p new
  • 在 Linq 查询中使用动态列名称

    foreach Dimension dimensions in Enum GetValues typeof Dimension var r new ReferenceTable dimensions referenceItems List
  • “DeploymentItem”属性是什么意思?

    假设我们有一个简短的程序 namespace ConsoleTryIt static class Program static void Main string args var sum Add 1 2 private static int
  • 我的代码哪里有泄漏?

    下面是我的代码 它打开一个 XML 文件 old xml 过滤无效字符并写入另一个 XML 文件 abc xml 最后 我将再次加载 XML abc xml 当执行以下行时 出现异常 表示 xml 文件被另一个进程使用 xDoc Load
  • 从 AuthorizeAttribute 继承的属性不起作用

    我目前正在尝试根据用户角色在新的 ASP MVC 5 应用程序中实现安全性 目标是防止用户在没有特定角色 或更高角色 的情况下访问某些控制器或控制器方法 根据到目前为止我所读到的问题 我创建了一个继承 AuthorizeAttribute
  • 如何在realm-dotnet中存储System.Collections.Generic.Dictionary

    我正在尝试将 Realm NET 集成到我的 uwp 项目中 我想知道是否有任何方法可以在 Realm dotnet 库中存储 System Collections Generic Dictionary 我试过这个 public class
  • 使用 DataGridViewCheckboxCell 真正禁用 DataGridView 中的复选框

    有谁知道如何使用 DataGridViewCheckboxCell 禁用 DataGridView 中的复选框 我可以将其设置为只读 并设置背景颜色 但我无法让复选框本身显示为禁用状态 有什么想法吗 Guess 你必须自己画 http so
  • 无法在 MARSHAMALLOW 文件选择器中选择 pdf、doc、ppt 等文件

    我正在使用我的 Android 应用程序将 pdf ppt doc 等文件上传到服务器 但在 Marshmallow 中 当文件选择器打开并且我浏览我的 Sdcard 或内部存储时 存在两个问题 1 它显示了所有我无法选择的文件 例如图像
  • 如何从 C# 中的 Web Api 方法正确获取字节数组?

    我有以下控制器方法 HttpPost Route SomeRoute public byte MyMethod FromBody string ID byte mybytearray db getmybytearray ID working
  • 从 C/C++ 程序进行 Ping

    我想编写一个 C 或 C 程序 给定一个 IP 地址 对其进行 Ping 然后根据 Ping 是否成功执行进一步的操作 这个怎么做 尽情享受Ping 页面 http www ping127001 com pingpage htm 其中有一个

随机推荐

  • 子模块的相对导入

    在Python中 我如何执行与以下内容等效的操作 import http client 但使用相对导入 from import http client import http client 对于一个包http在当前包中 我想然后访问clie
  • 铯标签模糊

    我使用以下代码创建了一个 Cesium 标签 var label Cesium LabelGraphics new Cesium LabelGraphics text lab verticalOrigin Cesium VerticalOr
  • 对于 Int32 来说值太大或太小 - Facebook 和 dotnetopenauth

    我正在尝试获取一个与 dotnetopenauth 和 facebook 一起使用的示例项目 我有这个代码 namespace OAuthClient using System using System Configuration usin
  • 使用聚合函数和 SELECT 进行更新

    我正在尝试编写一条 SQL 指令来更新与所有交货和订单总数相关的数据库库存产品数量 UPDATE tbl Product SET tbl Product Quantity Q Quantity FROM tbl Product INNER
  • CLR 内存不足异常

    我们遇到了很多内存不足的异常 但我们似乎无法诊断发生了什么 这似乎是一个在几分钟内内存使用量从 300 MB 飙升至超过 1 GB 的问题 现在这是一个IIS https en wikipedia org wiki Internet Inf
  • pandas agg 和 apply 函数有什么区别?

    我分不清熊猫之间的区别 aggregate and apply功能 以以下为例 我加载一个数据集 执行groupby 定义一个简单的函数 和任一用户 agg or apply 正如您所看到的 我的函数中的打印语句会产生相同的输出 使用后 a
  • 从C#中的角度计算圆圆周上的点?

    我想这是一个简单的问题 但我当前的代码得到了一些奇怪的结果 而且我没有数学背景来完全理解原因 我的目标很简单 如标题所示 我只想找到距中心点一定距离和角度的点 我当前的代码 Point centerPoint new Point 0 0 P
  • 将 MySQL 查询转换为 Codeigniter 语法

    我在将 MYSQL 查询转换为 CI 语法时遇到一些问题 这是我的 MySQL 语法 select a pbj name as NAMA PERUSAHAAN count a id pbj as JUMLAH PAKET group con
  • Clojure:懒惰魔法

    几乎 2 个相同的程序可以生成无限惰性的随机序列 第一个不会崩溃 第二次崩溃 出现 OutOfMemoryError 异常 为什么 Return infinite lazy sequence of random numbers defn i
  • 加盐你的密码:最佳实践? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我一直很好奇 对密码进行加盐以进行哈希处理时 前缀还是后缀哪个更好 为什么 或者只要你加盐就没关系吗 解释一下 我们现在 希望 都知道我们应该s
  • 在 IntelliJ Idea 中禁用代码折叠?

    如何在 IntelliJ idea 中禁用 或隐藏 这部分 Go to 文件 gt 设置 gt 编辑器 gt 常规 gt 代码折叠 Uncheck 显示代码折叠轮廓
  • 如何通过将所有选项放入 mongodb 的 Node.js 驱动程序的连接字符串中来连接 X509?

    我正在使用可用的密钥mongodb 文档 http mongodb github io node mongodb native 3 6 api MongoClient html使用带有 Node js 驱动程序的 X509 身份验证的自签名
  • 将 speedtest.net api 与 React Native 结合使用

    我正在创建一个 Android React Native 应用程序并尝试使用速度测试 net api https github com ddsol speedtest net获取移动设备的上传和下载速度 但是 当我尝试将库集成到 React
  • SQL Server 2008 中的检查约束

    拜托 我刚刚开始学习 SQL 并且陷入困境 我正在尝试为我的测试项目构建一个数据库 我创建了一些表 做了关系 定义了主键和外键 所有这些都在 SQL Server 2008 中通过可视化界面 表设计 编辑 没有声明编码 还没有到达那里 但我
  • 在 Sublime Text 中,如何查找和替换文件名

    在 Sublime Text 中有没有一种方法可以找到模式并将其替换为文件名 例如 我有一堆包含人物的文件名 我想用人来代替它 in SideBarEnhancements有一个选项Mass Rename Selection under F
  • Apache HTTP 连接与 Android 6.0 (Marshmallow)

    有没有办法将 Apache 库直接包含在 Gradle 中以使其与 Android 6 0 一起使用 我尝试包含这样的库 compile org apache httpcomponents httpcore 4 4 1 compile or
  • 代号一号如何运作?

    我正在寻找针对多个移动平台进行开发的替代方案 并发现代号一 http www codenameone com 使用 Java 作为通用语 而不是 HTML CSS JS 或脚本语言 我找不到的是它是如何工作的 它是否将 JVM 与 iOS
  • 使用 Google 跟踪代码管理器从 URL 中删除查询字符串

    我试图通过从 URL 中删除查询字符串来整理 Google Analytics 中的分析 但这分为三个要求 我想删除 GA 分析中显示的查询字符串 竞选 UTM 仍然需要发挥作用 阻止 UTM 中收集的任何 PII 攻击 GA 我发现了许多
  • 用于使用私有组件进行单元测试的 CocoaPods 项目结构

    我正在将 CocoaPods 用于具有以下结构的项目 Example Example PublicUmbrellaHeader h Example PrivateHeaderForComponent1 h Example PrivateHe
  • 使用 iText 自定义签名外观

    我正在尝试使用 iText sharp 版本 5 5 13 创建自定义数字签名 用户可以从一组四个位置 顶部 底部 左侧和右侧 设置图像位置 如下所示 Rigth Left Top Bottom 到目前为止 我尝试在签名的第 0 层上工作