首页 > 解决方案 > 使用 iText 自定义签名外观

问题描述

我正在尝试使用 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 层中的图像没有按应有的比例缩放)

right_signed

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

img_rigth_scaled

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

标签: c#pdfitextdigital-signature

解决方案


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

这将产生以下签名:

签名结果

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


推荐阅读