当前位置: 首页 > 知识库问答 >
问题:

使用iText自定义签名外观

荣波
2023-03-14

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

刚度:

左:

顶部:

底部:

到目前为止,我试着处理签名的第0层,但我认为我做得不对,因为签名细节是在第2层设置的。

然而,这只是设置图像位置的初始草图。在下面的代码中,我加载图像并将其放入一个块中(想法取自此示例)

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层中的图像没有按应有的比例缩放)

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

有什么方法可以“开箱即用”,或者我需要重载构建签名外观的方法(像这样),我如何实现这一点?

共有1个答案

狄雅珺
2023-03-14

我最初的音乐会是不使用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;
    }
}

这将导致以下签名:

当然,它还需要一些改进,但它可以作为其他人的榜样:-)

 类似资料:
  • 首先,虽然我关注StackOverflow已经有相当一段时间了,但这是我第一次发布一些东西,所以如果我做错了或者不按规则做的话,请随时为我指出正确的方向。 我正在开发一个PDF数字签名应用程序,使用iText5,它依赖于一个外部服务,在我准备好PDF签名后提供一个签名哈希。 如iText文档中所述,在第一阶段,我准备了PDF(在最终实现中,所有PDF都可能是多签名的,因此我使用追加模式),如下所示

  • 第一个选项是不可行的,因为PDF的签名没有时间戳(这是一个非常重要的必要条件),所以选择了第二个选项。 这是我们的代码,首先,我们得到签名外观,并计算散列: 在这一点上,我们有了文档的哈希代码。然后我们将散列发送到webservice,我们得到签名的散列代码。 按照mkl的建议,我遵循了这本书的4.3.3部分PDF文档的数字签名,现在我的代码如下: 第一部分,当我们计算散列时: 在第二部分,我们得

  • 我已经玩弄了一段时间的iTextSharp 5.5.7,找不到正确的方法从智能卡为PDF制作一个有效的数字签名-Adobe Reader总是说它的签名人和未知,并且不能解码签名的DER数据。 我查看了Makesignature.cs代码以供参考,以及is的功能: 然后,根据iExternalSignature.cs中的“Sign”方法 “@param message要进行散列和签名的邮件” 所以我

  • 我有一个简单的签名方法来签署工作正常的PDF文档,它使用显示名称、位置、日期和原因的默认戳记来签署文档。 现在我的经理问我是否可以在上面再添加一个字段。让我们假设这是一个“电子邮件”字段,因为我还没有被告知他们想要什么。 我试着搜索并应用我找到的一些东西,但没有任何效果。 此外,有人问我是否可以删除/隐藏这4个默认字段的标签(日期、原因等...),我无法管理这样做,也找不到任何关于它的东西,我不知

  • 我试图从PDF/A-1A输入文件创建签名的PDF,输出必须保持一致性级别。 签名必须添加定制外观。 如果我沿着下面的代码行进行操作,所有的东西都在签名端工作,签名被正确显示并验证为OK。 但PDF/A一致性被不包含所需toUnicode CMAP的嵌入式字体打破。 所以我想这里少了些什么。嵌入的字体不符合PDF/A,因为它们缺少ToUnicode CMAP键。pdf tools validator