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

Razor页面嵌入PDF后实现数字签名功能的技术问询

在Razor页面嵌入PDF实现数字签名的解决方案

问题根源

浏览器通过<object>标签内嵌的PDF默认使用浏览器内置PDF阅读器(如Chrome的PDFium、Edge的内置阅读器),这类阅读器不支持Adobe Reader/Acrobat的完整数字签名功能,所以看不到“通过输入或绘制签名签署文档”的菜单。


方案一:强制用Adobe Reader内嵌打开PDF(内网易统一配置)

通过给<object>标签添加Adobe专属的ActiveX参数,强制调用本地安装的Adobe Reader打开内嵌PDF,这样就能启用签名功能。

修改你的Razor后端代码中的embed字符串:

public IActionResult Index()
{
    string embed = @"<object data=""{0}"" type=""application/pdf"" width=""1000px"" height=""1000px"" 
                    classid=""clsid:CA8A9780-280D-11CF-A24D-444553540000"" 
                    pluginspage=""http://get.adobe.com/reader/"">
                        <param name=""toolbar"" value=""1"">
                        <param name=""navpanes"" value=""1"">
                        <param name=""scrollbar"" value=""1"">
                        <param name=""allowPrinting"" value=""1"">
                        <param name=""allowSigning"" value=""1"">
                        If you are unable to view file, you can download from <a href=""{0}"">here</a>
                        or use Adobe PDF Reader to view the file.
                    </object>";

    TempData["Embed"] = string.Format(embed, "/BlankPDFFiles/Test.pdf");
    return View();
}

注意:需要内网员工的电脑都安装Adobe Reader,并且浏览器允许加载ActiveX插件(可通过组策略统一配置)。


方案二:使用PDF.js实现网页内签名(开源无依赖)

用Mozilla开源的PDF.js在网页中渲染PDF,再通过Canvas实现签名绘制,最后将签名叠加到PDF画布或修改PDF文件。

步骤:

  1. 下载PDF.js包,部署到内网服务器的wwwroot/pdfjs目录下。
  2. 在Razor页面中添加以下代码:
<div id="pdfContainer" style="width: 1000px; height: 1000px;"></div>
<button id="drawSignBtn">绘制签名</button>
<button id="savePdfBtn">保存签名后的PDF</button>

<script src="/pdfjs/build/pdf.js"></script>
<script>
    // 配置PDF.js工作线程路径
    pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdfjs/build/pdf.worker.js';

    let pdfDoc = null;
    let pageCanvas = null;

    // 加载PDF
    async function loadPdf() {
        const pdfUrl = '/BlankPDFFiles/Test.pdf';
        pdfDoc = await pdfjsLib.getDocument(pdfUrl).promise;
        const page = await pdfDoc.getPage(1);
        const viewport = page.getViewport({ scale: 1.5 });

        pageCanvas = document.createElement('canvas');
        pageCanvas.width = viewport.width;
        pageCanvas.height = viewport.height;
        document.getElementById('pdfContainer').appendChild(pageCanvas);

        await page.render({
            canvasContext: pageCanvas.getContext('2d'),
            viewport: viewport
        }).promise;
    }

    // 绘制签名
    let isDrawing = false;
    let signCanvas = null;
    document.getElementById('drawSignBtn').addEventListener('click', () => {
        signCanvas = document.createElement('canvas');
        signCanvas.width = 200;
        signCanvas.height = 100;
        signCanvas.style.border = '1px solid #000';
        signCanvas.style.marginTop = '10px';
        document.getElementById('pdfContainer').appendChild(signCanvas);

        const ctx = signCanvas.getContext('2d');
        ctx.lineWidth = 2;
        ctx.strokeStyle = '#000';

        signCanvas.addEventListener('mousedown', e => {
            isDrawing = true;
            ctx.beginPath();
            ctx.moveTo(e.offsetX, e.offsetY);
        });

        signCanvas.addEventListener('mousemove', e => {
            if (isDrawing) {
                ctx.lineTo(e.offsetX, e.offsetY);
                ctx.stroke();
            }
        });

        signCanvas.addEventListener('mouseup', () => {
            isDrawing = false;
            // 将签名绘制到PDF页面的指定位置(示例:X=150, Y=550)
            const pdfCtx = pageCanvas.getContext('2d');
            pdfCtx.drawImage(signCanvas, 150, pageCanvas.height - 550, 200, 100);
        });
    });

    // 保存签名后的PDF(需要额外库如pdf-lib,此处为简化示例)
    document.getElementById('savePdfBtn').addEventListener('click', async () => {
        // 若需真正修改PDF文件内容,可引入pdf-lib库实现签名嵌入
        // 此处仅演示将Canvas转为图片下载
        const link = document.createElement('a');
        link.download = 'signed_pdf.png';
        link.href = pageCanvas.toDataURL();
        link.click();
    });

    // 初始化加载PDF
    loadPdf();
</script>

进阶说明:如果需要生成带合法数字证书的PDF签名,可搭配pdf-lib库,将签名和证书嵌入PDF文件,再上传到服务器。


方案三:服务器端添加签名域,用户下载签名后上传

用PDF处理库(如iTextSharp)在服务器端给PDF添加签名域,用户下载PDF后用Adobe Reader完成签名,再上传回服务器。

服务器端代码(C#):

using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;

public IActionResult GeneratePdfWithSignatureField()
{
    string inputPdfPath = Path.Combine(WebRootPath, "BlankPDFFiles/Test.pdf");
    string outputPdfPath = Path.Combine(WebRootPath, "BlankPDFFiles/Test_Signable.pdf");

    // 读取原PDF并添加签名域
    using (var reader = new PdfReader(inputPdfPath))
    using (var stamper = new PdfStamper(reader, new FileStream(outputPdfPath, FileMode.Create)))
    {
        AcroFields acroFields = stamper.AcroFields;
        // 添加签名域:参数依次为域名、页码、左下角X/Y、右上角X/Y
        acroFields.AddSignature("EmployeeSignature", 1, 100, 500, 300, 600);
        stamper.Close();
    }

    // 嵌入带签名域的PDF
    string embed = "<object data=\"{0}\" type=\"application/pdf\" width=\"1000px\" height=\"1000px\">";
    embed += "If you are unable to view file, you can download from <a href=\"{0}\">here</a> to sign with Adobe Reader.";
    embed += "</object>";

    TempData["Embed"] = string.Format(embed, "/BlankPDFFiles/Test_Signable.pdf");
    return View();
}

后续流程:

  1. 用户下载带签名域的PDF,用Adobe Reader打开后可直接在签名域中完成签名。
  2. 开发文件上传功能,让用户将签名后的PDF上传回服务器存储。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:37:52