目 录CONTENT

文章目录

HTML转换成pdf文件代码篇

Jacky
2024-08-22 / 0 评论 / 0 点赞 / 22 阅读 / 9101 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2024-10-12,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

之前做过一个在线签名的功能,具体的需求是,用户可以在线签名,可以对签名进行编辑,最终生成pdf的功能.

这次不聊在线签名,只谈html代码最后生成pdf导

这个功能需要用到两个组件来配合,先把html转换成canvas,然后在使用jspdf对canvas进行转换并下载

组件名称:[html2canvas],[jspdf],代码在github上,gitee也有,搜索名字就可以查到:yylcha.smooth-signature

github地址 JackySuen1994/yylcha.smoothSignature: 通过smoothsignature实现签名 (github.com)

SmoothSignature_CSharp

项目资源文件介绍

引用 html2canvas.js | jspdf.js 你copy过去也可以直接使用,这两个js是我们核心使用文件

js引用

HTML Code

<div>

    <div class="singPanel" id="overtimeApp">

        <table class="cssTb">

            <tr>

                <td>部门</td>

                <td></td>

                <td>姓名</td>

                <td>XXX</td>

                <td>职位</td>

                <td>.net开发</td>

            </tr>

            <tr>

                <td>加班事由</td>

                <td colspan="5">测试</td>

            </tr>

            <tr>

                <td>加班时间</td>

                <td colspan="5">

                    <span>日期:__2099__年__12__月__31__日(□工作日 □双休日 □国定假日)</span>

                    <br />

                    <span>时间:从__08__点到__18__点</span><br />

                    <span>共计__8__小时</span>

                </td>

            </tr>

            <tr>

                <td>换算方式</td>

                <td colspan="5"><span>□调休 □调休延期 □加班费</span></td>

            </tr>

            <tr>

                <td>实际加班时数(由HR填写)</td>

                <td colspan="3"></td>

                <td>人力资源部签收</td>

                <td></td>

            </tr>

        </table>

        <div class="cssWorld">

            <div style="float: left; width: 600px;margin-top:5px">

                <div style="float: left">申请部门经理签字:</div>

                <div class="dvCanvas">

                    <canvas style="border: 1px solid black"></canvas>

                </div>

            </div>

            <div style="float: right; width: 200px">

                  2099年  12月  31日

            </div>

            <div hidden id="hdnSignature"></div>

        </div>

    </div>

    <div class="cssBtn">

        <button class="btn btn-primary btn-sm" type="button" id="btnClear">清空签名</button>

        <button class="btn btn-primary btn-sm" type="button" id="btnUndo">撤销</button>

        <button class="btn btn-primary btn-sm" type="button" id="btnGeneraCanvas">确定</button>

        <button class="btn btn-primary btn-sm" type="button" id="btnHandleColor">修改字迹颜色</button>

        <br />

        <br />

        <button class="btn btn-primary" type="button" id="btnDownLoad">生成PDF</button>

    </div>

JavaScript Code

<script src="~/lib/jquery/dist/jquery.min.js"></script>

    <script src="~/lib/jquery/dist/jquery.js"></script><script src="~/js/smooth-signature.min.js"></script>

    <script src="~/js/smooth-signature.js">

    </script><script src="~/js/html2canvas.js"></script><script src="~/js/jspdf.js"></script>

    <script>

        $(function () {

            //获取定义画布

            let canvas = document.querySelector("canvas");

            //画布参数

            let options = {

                width: Math.min(window.innerWidth, 370),//宽度

                height: 200,//高度

                minWidth: 4,

                maxWidth: 12,

                // color: '1890ff',

                bgColor: "f6f6f6",

            };

            //初始化smoothsignature画布

            var signature = null;

            if (canvas) {

                signature = new SmoothSignature(canvas, options);

            }

            //生成pdf时间

            $("btnDownLoad").click(function () {

                //需要打印的html

                var html = document.getElementById("overtimeApp");

                //使用html2canvas把html元素转换成canvas

                //jsPDF 把canvas转换成pdf并导出

                html2canvas(html).then(function (canvas) {

                    //获取html转成canvas的宽度和高度

                    var canvasWidth = canvas.width;

                    var canvasHeight = canvas.height;

                    // 创建PDF文档对象

                    var pdf = new jsPDF('p', 'pt', 'a4');

                    //通过canvas的宽高计算pdf页面的大小,自适应pdf

                    var scaleFactor = pdf.internal.pageSize.width / canvasWidth;

                    var scaleHeight = canvasHeight * scaleFactor;

                    // 将canvas转化为图片并添加至PDF文档

                    pdf.addImage(canvas.toDataURL('image/png'), 'JPEG', 20, 30, pdf.internal.pageSize.width - 40, scaleHeight);

                    // 下载PDF文档

                    pdf.save('加班申请单.pdf');

                });

            });

            //清除签名画布

            $("btnClear").click(function () {

                if (signature) {

                    signature.clear();

                } else {

                    alert("画布初始化失败!");

                }

            });

            //返回上一步

            $("btnUndo").click(function () {

                if (signature) {

                    signature.undo();

                } else {

                    alert("画布初始化失败!");

                }

            });

            //把签名画布转换成image标签-未使用

            $("btnGeneraCanvas").click(function () {

                if (signature) {

                    var pngUrl = signature.getPNG();

                    var blob = this.dataURLToBlob(pngUrl);

                    var url = window.URL.createObjectURL(blob);

                    $("hdnSignature").attr(`<img src='${url}'></img>`)

                } else {

                    alert("画布初始化失败!");

                }

            });

            //更改笔线颜色

            $("btnHandleColor").click(function () {

                if (signature) {

                    signature.color = "" + Math.random().toString(16).slice(-6);

                } else {

                    alert("画布初始化失败!");

                }

  

            });

        })

        //把image转换成blob

        function dataURLToBlob(dataURL) {

            // Code taken from https://github.com/ebidel/filer.js

            const parts = dataURL.split(";base64,");

            const contentType = parts[0].split(":")[1];

            const raw = window.atob(parts[1]);

            const rawLength = raw.length;

            const uInt8Array = new Uint8Array(rawLength);

            for (let i = 0; i < rawLength; ++i) {

                uInt8Array[i] = raw.charCodeAt(i);

            }

            return new Blob([uInt8Array], { type: contentType });

        }

    </script>

Css Code

<style>

        .cssSign {

            height: 200px;

            width: 440px;

            float: right;

        }

        .cssTb {

            margin: auto;

            width: 40%;

        }

        .cssWorld {

            margin: auto;

            width: 40%;

        }

        table,

        td {

            border: 1px solid black;

            width: 500px;

        }

        .cssBtn {

            margin-top: 300px;

            text-align: center;

        }

        .singPanel {

            width: 100%;

            height: 400px;

        }

    </style>

QA

Q:为什么不直接使用jspdf来实现html转换成pdf呢?

A:这个问题我试过,jspdf是支持把html直接导出成pdf的,但是会有一个问题,中文会出现乱码的

再加上原来的签名组件是一个canvas,所以我使用了这个办法,后续其他的项目应用我也都是这样处理的

逻辑原理

  1. 把html代码转换成canvas

  2. jspdf把canvas转换成pdf

  3. 导出

0

评论区