Newer
Older
casic-production-safety / sql / test3.html
liwenhao on 6 Jun 9 KB 1.测评问题整改
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <script src="https://libs.baidu.com/jquery/1.9.1/jquery.js"></script>
    <script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.2/jspdf.umd.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/hanzi-writer@3.0/dist/hanzi-writer.min.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        body {
            font-family: "msyh";
            letter-spacing: 0.01px; /*解决jspdf的英文字母间隔问题  */
        }
        table {
            font-size: 2.5rem;
            border-spacing: 0.5rem;
            border: 1px solid black;
        }
        table.tb_cn tr td {
            width: 3.45rem;
            height: 3.45rem;
            line-height: 3.45rem;
            text-align: center;
            color: rgb(153, 153, 153);
            border: 1px solid black;
        }
        table.tb_cn tr td :nth-child(odd) {
            height: 2rem;
            line-height: 2rem;
        }
        table tr td:first-child {
            color: black;
        }
        table tr td.with-line {
            position: relative;
        }
        table tr td.with-line::before {
            content: "";
            position: absolute;
            height: 1px;
            width: 100%;
            left: 0;
            top: 50%;
            transform: translateY(-50%);
            border-top: 1px dashed silver;
            z-index: -1;
        }
        table tr td.with-line::after {
            content: "";
            position: absolute;
            height: 100%;
            width: 1px;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            border-left: 1px dashed silver;
            z-index: -1;
        }
        table.tb_img tr td {
            width: 6 * 3.45rem;
            height: 4 * 3.45rem;
            line-height: 6 * 3.45rem;
            text-align: center;
            border: 1px solid black;
            padding: 0.25rem;
        }
        #container {
            display: flex;
        }
        #content-con {
            width: 210mm;
        }
        #content-con .content {
            height: 300.5mm;
        }
    </style>
</head>
<body>
<div id="container">
    <div id="content-con"></div>
    <div id="toolbar">
        <textarea id="text" type="textarea" onchange="changeContent()" rows="5">你好世界你好世界你好世界你好世界你好世界</textarea>
        <br />
        <button onclick="exportPdf('content-con')">export Pdf</button>
    </div>
</div>
</body>
<script>
    const gbl_param = {
        page_num: 3,
        cn_col_num: 12,
        cn_row_num: 8,
        char_size: 36,
        img_bg_id: 0,
        img_row_num: 2,
        img_col_num: 3,
    };

    function exportPdf(domId) {
        html2canvas(document.getElementById(domId)).then((canvas) => {
            const contentWidth = canvas.width;
            const contentHeight = canvas.height;
            console.log("content", contentWidth, contentHeight);

            const s_w = 595.28;
            const s_h = 841.89;
            const sd_w = 7;

            const pageHeight = (contentWidth / s_w) * s_h; //每页pdf的canvas高度;
            console.log("page", pageHeight);

            let leftHeight = contentHeight; //未生成pdf的canvas高度
            let position = 10; //pdf页面偏移

            //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
            const imgWidth = s_w - sd_w;
            // const imgWidth = s_w;
            const imgHeight = (imgWidth / contentWidth) * contentHeight; //canvas转为图片后适配A4纸宽度的高度
            console.log("img", imgWidth, imgHeight);

            const pageData = canvas.toDataURL("image/jpeg", 1.0);

            const pdf = new jspdf.jsPDF("p", "pt", "a4");
            //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
            //当内容未超过pdf一页显示的范围,无需分页
            if (leftHeight < pageHeight) {
                pdf.addImage(pageData, "JPEG", sd_w, position, imgWidth, imgHeight);
            } else {
                while (leftHeight > 0) {
                    pdf.addImage(pageData, "JPEG", sd_w, position, imgWidth, imgHeight);
                    leftHeight -= pageHeight;
                    position -= s_h;

                    console.log("leftHeight", leftHeight);
                    // console.log("position", position);
                    //避免添加空白页
                    if (leftHeight > 0) {
                        pdf.addPage();
                    }
                }

                let targetPage = pdf.internal.getNumberOfPages();
                pdf.deletePage(targetPage); // 删除最后一页
            }

            // pdf.save("xxxx.pdf");
            window.open(pdf.output("bloburl")); //预览pdf
        });
    }

    function renderFanningStrokes(target, strokes) {
        const char_size = gbl_param.char_size;
        // createElementNS() 方法可创建带有指定命名空间的元素节点
        const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        svg.style.width = char_size + "px";
        svg.style.height = char_size + "px";
        svg.style.border = "1px solid #EEE";
        svg.style.marginRight = "3px";
        target.appendChild(svg);
        const group = document.createElementNS("http://www.w3.org/2000/svg", "g");

        const transformData = HanziWriter.getScalingTransform(char_size, char_size);
        group.setAttributeNS(null, "transform", transformData.transform);
        svg.appendChild(group);

        strokes.forEach(function (strokePath) {
            const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
            path.setAttributeNS(null, "d", strokePath);
            path.style.fill = "#555";
            group.appendChild(path);
        });
    }

    function getCharOrder(domId, char_cn) {
        HanziWriter.loadCharacterData(char_cn).then(function (charData) {
            const target = document.getElementById(domId);
            target.innerHTML = "";
            for (let i = 0; i < charData.strokes.length; i++) {
                const strokesPortion = charData.strokes.slice(0, i + 1);
                renderFanningStrokes(target, strokesPortion);
            }
        });
    }

    function changeContent() {
        let str = $("#text").val();
        if (str.length < gbl_param.page_num * Math.floor(gbl_param.cn_row_num / 2) || containsNonChineseChar(str)) return;

        const cn_char_num = Math.floor(gbl_param.cn_row_num / 2);
        let cnt = 0;
        for (let i = 0; i < gbl_param.page_num; i++) {
            for (let j = 0; j < cn_char_num; j++) {
                getCharOrder("charOrder" + cnt, str[cnt]);
                $(".content .tb_cn")
                    .eq(i)
                    .find("tr")
                    .eq(2 * j + 1)
                    .find("td")
                    .text(str[cnt]);
                cnt++;
            }
        }
    }
    initPage();
    changeContent();

    function initPage() {
        const cn_col_num = gbl_param.cn_col_num;
        const cn_row_num = gbl_param.cn_row_num;

        $("#content-con").html("");
        let cnt = -1;
        for (let i = 0; i < gbl_param.page_num; i++) {
            $("#content-con").append(
                "<div class='content'><table class='tb_cn'>" +
                Array(cn_row_num)
                    .fill(null)
                    .map((val, idx) => {
                        if (idx % 2 == 0) {
                            cnt++;
                            return `<tr><td id="charOrder${cnt}" colspan="${cn_col_num}"></td></tr>`;
                        } else {
                            return `<tr>${Array(cn_col_num)
                                .fill(null)
                                .map((val, idx) => {
                                    return `<td class="with-line"></td>`;
                                })
                                .join("")}
                    </tr>`;
                        }
                    })
                    .join("") +
                "</table><table class='tb_img'>" +
                Array(gbl_param.img_row_num)
                    .fill(null)
                    .map((val, idx) => {
                        gbl_param.img_bg_id += 1;
                        const url = "./images/test_svg/" + "0".repeat(5 - gbl_param.img_bg_id.toString().length) + gbl_param.img_bg_id + ".svg";
                        return `<tr>${Array(gbl_param.img_col_num)
                            .fill(null)
                            .map((val, idx) => {
                                return `<td><img src="${url}" width="240" height="240" ></td>`;
                            })
                            .join("")}</tr>`;
                    })
                    .join("") +
                "</table></div>"
            );
        }
    }

    function containsNonChineseChar(str) {
        return /[^\u4e00-\u9fa5]/.test(str);
    }
</script>
</html>