纯html js 写一个小工具,收据模板

纯html js 写一个小工具,收据模板

特点。自动计算金额。自动转换大写。记录例如输入内容。

源码如下。有需要的可以使用。若有啥优化。欢迎改善指点。

<html lang="zh-CN">
<head>
    <style type="text/css">
        .shoukuangshouju {
            width: 190mm;
            height: 105mm;
            border: 4px solid darkgray;
            margin: 0 auto;
            padding: 4px;
        }

        .biaoti {
            font-size: 30px;
            letter-spacing: 10px;
            font-weight: bold;
            text-align: center;
        }

        .bianhao {
            font-size: 14px;
            position: relative;
            top: -20px;
            right: 30px;
            float: right;
            display: flex;
        }

        .riqi {
            font-size: 12px;
            position: relative;
            right: 30px;
            float: right;
        }

        .biao_ge td {
            background-color: #FFF;
            text-align: center;
        }

        .biao_ge2 {
            background-color: #000;
        }

        .inputtop {
            border-bottom-width: 1px;
            border-style: none none solid none;
        }

        .input1 {
            border-style: none;
            width: calc(100% - 6px);
        }

        .input2 {
            border-style: none;
            width: calc(100% - 6px);
            text-align: center; /* 内容居中 */
        }

        .input3 {
            border-bottom-width: 1px;
            border-style: none none solid none;
            width: calc(100% - 7em);
        }

        .input4 {
            border-bottom-width: 1px;
            border-style: none none solid none;
            width: calc(100% - 6em);
        }

        .inputm {
            width: 100%;
            border-style: none;
        }

        .center-input {
            text-align: center; /* 内容居中 */
        }
    </style>
</head>
<body>
    <div class="shoukuangshouju">
        <table width="100%" border="0" align="center">
            <tbody>
                <tr>
                    <td>
                        <div class="biaoti">收款收据</div>
                        <div class="bianhao">No.<input class="persist-input" data-storage-key="bianhao" style="border-style: none;width:80px" /></div>
                    </td>
                </tr>
                <tr>
                    <td>
                        客户名称:<input class="inputtop persist-input" data-storage-key="kehumingcheng" list="list" id="liss" style="width: calc(100% - 300px);">
                        <div class="riqi">
                            <input name="shi_jian_nian" data-storage-key="nian" maxlength="4" style="width:40px;" class="inputtop center-input persist-input" value="2025"><input name="shi_jian_yue" maxlength="2" style="width:20px;" class="inputtop center-input persist-input" data-storage-key="yue"><input name="shi_jian_ri" maxlength="2" style="width:20px;" class="inputtop center-input persist-input" data-storage-key="ri"></div>
                    </td>
                </tr>
            </tbody>
        </table>

        <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" class="biao_ge">
            <tbody>
                <tr>
                    <td>
                        <table width="100%" border="0" class="biao_ge2" cellpadding="3" cellspacing="1">
                            <tbody>
                                <tr>
                                    <td rowspan="2">名称及规格</td>
                                    <td rowspan="2" width="50">单位</td>
                                    <td rowspan="2" width="60">数量</td>
                                    <td rowspan="2" width="80">单价</td>
                                    <td colspan="9">金额</td>
                                </tr>
                                <tr>
                                    <td width="22"></td>
                                    <td width="22"></td>
                                    <td width="22"></td>
                                    <td width="22"></td>
                                    <td width="22"></td>
                                    <td width="22"></td>
                                    <td width="22"></td>
                                    <td width="22"></td>
                                    <td width="22"></td>
                                </tr>
                                <tr>
                                    <td>
                                        <input name="ming_cheng" class="input1 persist-input" data-storage-key="ming_cheng1" />
                                    <td>
                                        <input name="dan_wei" class="input2 center-input persist-input" data-storage-key="dan_wei1" />
                                    <td>
                                        <input name="shu_liang" class="input2 center-input persist-input" data-storage-key="shu_liang1" onchange="dan_xiang_jia_ge_ji_suan(0)" />
                                    <td>
                                        <input name="dan_jia" class="input2 center-input persist-input" data-storage-key="dan_jia1" onchange="dan_xiang_jia_ge_ji_suan(0)" />
                                    <td>
                                        <input name="jin_e_bai_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_shi_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_qian" class="input2" />
                                    <td>
                                        <input name="jin_e_bai" class="input2" />
                                    <td>
                                        <input name="jin_e_shi" class="input2" />
                                    <td>
                                        <input name="jin_e_yuan" class="input2" />
                                    <td>
                                        <input name="jin_e_jiao" class="input2" />
                                    <td>
                                        <input name="jin_e_fen" class="input2" />
                                </tr>
                                <tr>
                                    <td>
                                        <input name="ming_cheng" class="input1 persist-input" data-storage-key="ming_cheng2" />
                                    <td>
                                        <input name="dan_wei" class="input2 center-input persist-input" data-storage-key="dan_wei2" />
                                    <td>
                                        <input name="shu_liang" class="input2 center-input persist-input" data-storage-key="shu_liang2" onchange="dan_xiang_jia_ge_ji_suan(1)" />
                                    <td>
                                        <input name="dan_jia" class="input2 center-input persist-input" data-storage-key="dan_jia2" onchange="dan_xiang_jia_ge_ji_suan(1)" />
                                    <td>
                                        <input name="jin_e_bai_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_shi_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_qian" class="input2" />
                                    <td>
                                        <input name="jin_e_bai" class="input2" />
                                    <td>
                                        <input name="jin_e_shi" class="input2" />
                                    <td>
                                        <input name="jin_e_yuan" class="input2" />
                                    <td>
                                        <input name="jin_e_jiao" class="input2" />
                                    <td>
                                        <input name="jin_e_fen" class="input2" />
                                </tr>
                                <tr>
                                    <td>
                                        <input name="ming_cheng" class="input1 persist-input" data-storage-key="ming_cheng3" />
                                    <td>
                                        <input name="dan_wei" class="input2 center-input persist-input" data-storage-key="dan_wei3" />
                                    <td>
                                        <input name="shu_liang" class="input2 center-input persist-input" data-storage-key="shu_liang3" onchange="dan_xiang_jia_ge_ji_suan(2)" />
                                    <td>
                                        <input name="dan_jia" class="input2 center-input persist-input" data-storage-key="dan_jia3" onchange="dan_xiang_jia_ge_ji_suan(2)" />
                                    <td>
                                        <input name="jin_e_bai_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_shi_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_qian" class="input2" />
                                    <td>
                                        <input name="jin_e_bai" class="input2" />
                                    <td>
                                        <input name="jin_e_shi" class="input2" />
                                    <td>
                                        <input name="jin_e_yuan" class="input2" />
                                    <td>
                                        <input name="jin_e_jiao" class="input2" />
                                    <td>
                                        <input name="jin_e_fen" class="input2" />
                                </tr>
                                <tr>
                                    <td>
                                        <input name="ming_cheng" class="input1 persist-input" data-storage-key="ming_cheng4" />
                                    <td>
                                        <input name="dan_wei" class="input2 center-input persist-input" data-storage-key="dan_wei4" />
                                    <td>
                                        <input name="shu_liang" class="input2 center-input persist-input" data-storage-key="shu_liang4" onchange="dan_xiang_jia_ge_ji_suan(3)" />
                                    <td>
                                        <input name="dan_jia" class="input2 center-input persist-input" data-storage-key="dan_jia4" onchange="dan_xiang_jia_ge_ji_suan(3)" />
                                    <td>
                                        <input name="jin_e_bai_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_shi_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_qian" class="input2" />
                                    <td>
                                        <input name="jin_e_bai" class="input2" />
                                    <td>
                                        <input name="jin_e_shi" class="input2" />
                                    <td>
                                        <input name="jin_e_yuan" class="input2" />
                                    <td>
                                        <input name="jin_e_jiao" class="input2" />
                                    <td>
                                        <input name="jin_e_fen" class="input2" />
                                </tr>
                                <tr>
                                    <td>
                                        <input name="ming_cheng" class="input1 persist-input" data-storage-key="ming_cheng5" />
                                    <td>
                                        <input name="dan_wei" class="input2 center-input persist-input " data-storage-key="dan_wei5" />
                                    <td>
                                        <input name="shu_liang" class="input2 center-input persist-input" data-storage-key="shu_liang5" onchange="dan_xiang_jia_ge_ji_suan(4)" />
                                    <td>
                                        <input name="dan_jia" class="input2 center-input persist-input" data-storage-key="dan_jia5" onchange="dan_xiang_jia_ge_ji_suan(4)" />
                                    <td>
                                        <input name="jin_e_bai_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_shi_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_wan" class="input2" />
                                    <td>
                                        <input name="jin_e_qian" class="input2" />
                                    <td>
                                        <input name="jin_e_bai" class="input2" />
                                    <td>
                                        <input name="jin_e_shi" class="input2" />
                                    <td>
                                        <input name="jin_e_yuan" class="input2" />
                                    <td>
                                        <input name="jin_e_jiao" class="input2" />
                                    <td>
                                        <input name="jin_e_fen" class="input2" />
                                </tr>
                                <tr>
                                    <td colspan="1">合计金额(大写)</td>
                                    <td colspan="6"><input id="jinedaxie" class="inputm"></td>
                                    <td colspan="1"></td>
                                    <td colspan="5"><input id="jinexiaoxie" class="inputm"></td>
                                </tr>
                            </tbody>
                        </table>
                    </td>
                    <td width="30"><br><br><br>
                        <br><br></td>
                </tr>
            </tbody>
        </table>
        <table width="100%" border="0" align="center">
            <tbody>
                <tr>
                    <td width="25%" height="30">填票:<input name="jin_e_fen" class="input4 persist-input" data-storage-key="tianxie" />
                    <td width="25%">收款:<input name="jin_e_fen" class="input4 persist-input" data-storage-key="shoukuan" />
                    <td width="50%">收款单位:<input name="jin_e_fen" class="input3 persist-input" data-storage-key="shoukuandanwei" />
                </tr>
                <tr>
                    <td colspan="3">备注:<input name="jin_e_fen" class="input4 persist-input" data-storage-key="beizhu" />
                </tr>
            </tbody>
        </table>
    </div>
    <script>
        function dan_xiang_jia_ge_ji_suan(index) {
            var shu_liang = document.getElementsByName("shu_liang")[index].value;
            var dan_jia = document.getElementsByName("dan_jia")[index].value;

            console.log(dan_jia * shu_liang);
            if (shu_liang !== "" && dan_jia !== "") {

                var jin_e = dan_jia * shu_liang;//计算出金额

                document.getElementsByName("jin_e_fen")[index].value = parseInt((jin_e * 100) % 10); // 分位数
                document.getElementsByName("jin_e_jiao")[index].value = parseInt((jin_e * 10) % 10); // 角位数
                document.getElementsByName("jin_e_yuan")[index].value = parseInt(jin_e % 10); // 个位数
                document.getElementsByName("jin_e_shi")[index].value = parseInt((jin_e % 100) / 10);  // 十位数
                document.getElementsByName("jin_e_bai")[index].value = parseInt((jin_e % 1000) / 100); // 百位数
                document.getElementsByName("jin_e_qian")[index].value = parseInt((jin_e % 10000) / 1000); // 千位数
                document.getElementsByName("jin_e_wan")[index].value = parseInt((jin_e % 100000) / 10000); // 万位数
                document.getElementsByName("jin_e_shi_wan")[index].value = parseInt((jin_e % 1000000) / 100000); // 十万位数
                document.getElementsByName("jin_e_bai_wan")[index].value = parseInt((jin_e % 10000000) / 1000000); // 百万位数
                // 以此类推
                console.log(jin_e);
            }

            //合计金额
            var shus = document.getElementsByName("shu_liang");
            var jias = document.getElementsByName("dan_jia");


            var money = 0;

            for (var i = 0; i < shus.length; i++) {
                var shu = shus[i];
                var jia = jias[i];

                money = money + shu.value * jia.value;

                console.log(shu);
                console.log(jia);
            }

            var jinexiaoxi = document.getElementById("jinexiaoxie");

            console.log(jinexiaoxi);
            jinexiaoxi.value = money;

            console.log(money);

            var daxie = numberToChinese(money);
            console.log(daxie);


            //填写金额大写值

            var jinedaxie = document.getElementById("jinedaxie");
            jinedaxie.value = daxie;

        }

        function numberToChinese(num) {
            // 1. 预处理:转数字、去空格、校验合法性
            num = Number(num.toString().trim());
            if (isNaN(num)) return '无效数字';
            if (num < 0) return '不支持负数';
            if (num > 9999999999999.99) return '数字超出最大支持范围(万亿级)';

            // 2. 定义基础字符
            const digitChars = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
            const unitChars = ['', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟', '万']; // 整数位单位
            const decimalUnit = ['角', '分']; // 小数位单位

            // 3. 拆分整数和小数部分(保留两位小数)
            const [integerPart, decimalPart = ''] = num.toFixed(2).split('.');
            let chineseStr = '';

            // 4. 处理整数部分
            if (integerPart !== '0') {
                // 遍历每一位数字
                for (let i = 0; i < integerPart.length; i++) {
                    const digit = parseInt(integerPart[i]);
                    const position = integerPart.length - 1 - i; // 位数位置(个位=0,十位=1...)
                    const unit = unitChars[position];

                    if (digit === 0) {
                        // 处理零:连续零只保留一个,且零后面不能跟单位(万/亿除外)
                        const nextDigit = parseInt(integerPart[i + 1] || 0);
                        if (
                            chineseStr.slice(-1) !== '零' &&
                            nextDigit !== 0 &&
                            position % 4 !== 0 // 非万/亿位
                        ) {
                            chineseStr += '零';
                        }
                        // 万/亿位特殊处理:即使当前位是0,也要保留单位(避免“壹亿零万”)
                        if ((position === 4 || position === 8) && chineseStr.slice(-1) !== '万' && chineseStr.slice(-1) !== '亿') {
                            chineseStr += unit;
                        }
                    } else {
                        // 非零数字:拼接数字+单位
                        chineseStr += digitChars[digit] + unit;
                    }
                }
                // 末尾加“元”
                chineseStr += '元';
            } else {
                // 整数部分为0时,小数部分非空才加“零”
                if (decimalPart !== '00') {
                    chineseStr += '零';
                } else {
                    // 全部为0时,直接返回“零元整”
                    return '零元整';
                }
            }

            // 5. 处理小数部分(角分)
            for (let i = 0; i < decimalPart.length; i++) {
                const digit = parseInt(decimalPart[i]);
                if (digit !== 0) {
                    chineseStr += digitChars[digit] + decimalUnit[i];
                }
            }

            // 6. 处理末尾:无小数时加“整”
            if (decimalPart === '00') {
                chineseStr += '整';
            }

            // 7. 清理冗余(如“零万”“零亿”)
            chineseStr = chineseStr.replace(/零万/g, '万');
            chineseStr = chineseStr.replace(/零亿/g, '亿');
            chineseStr = chineseStr.replace(/亿万/g, '亿'); // 修复“壹亿壹万”→“壹亿零壹万”
            chineseStr = chineseStr.replace(/零+/g, '零'); // 多个连续零合并为一个
            chineseStr = chineseStr.replace(/零元/g, '元'); // 修复“零元角分”→“元角分”
            chineseStr = chineseStr.replace(/零整$/, '整'); // 修复“零整”→“整”

            return chineseStr;
        }
    </script>
    <script>
        // 存储配置 - 统一管理存储相关配置
        const STORAGE_CONFIG = {
            // 统一的存储键名
            MAIN_KEY: 'persist_inputs_data',
            // 默认空数据对象
            DEFAULT_DATA: {}
        };

        // 工具函数:从 localStorage 获取统一的存储数据
        function getPersistData() {
            try {
                const rawData = localStorage.getItem(STORAGE_CONFIG.MAIN_KEY);
                return rawData ? JSON.parse(rawData) : { ...STORAGE_CONFIG.DEFAULT_DATA };
            } catch (error) {
                console.error('读取存储数据失败:', error);
                return { ...STORAGE_CONFIG.DEFAULT_DATA };
            }
        }

        // 工具函数:保存数据到 localStorage
        function savePersistData(data) {
            try {
                localStorage.setItem(STORAGE_CONFIG.MAIN_KEY, JSON.stringify(data));
                return true;
            } catch (error) {
                console.error('保存存储数据失败:', error);
                return false;
            }
        }

        // 初始化所有持久化输入框
        function initPersistInputs() {
            // 获取所有需要持久化的输入框
            const persistInputs = document.querySelectorAll('.persist-input');

            // 如果没有找到输入框,直接返回
            if (!persistInputs.length) {
                console.warn('未找到需要持久化的输入框 (.persist-input)');
                return;
            }

            // 1. 批量回填数据
            function restoreInputValues() {
                const savedData = getPersistData();

                persistInputs.forEach(input => {
                    const key = input.dataset.storageKey;
                    // 验证 key 是否存在
                    if (!key) {
                        console.warn('输入框缺少 storageKey 属性:', input);
                        return;
                    }

                    // 回填数据(如果有保存的值)
                    if (savedData.hasOwnProperty(key)) {
                        input.value = savedData[key];
                    }

                    console.log('已初始化输入框:', key, input);
                });
            }

            // 2. 批量绑定事件
            function bindInputEvents() {
                // 统一的 beforeunload 处理函数(只绑定一次)
                function handleBeforeUnload() {
                    const currentData = getPersistData();

                    persistInputs.forEach(input => {
                        const key = input.dataset.storageKey;
                        if (key) {
                            currentData[key] = input.value;
                        }
                    });

                    savePersistData(currentData);
                }

                // 为每个输入框绑定实时保存事件
                persistInputs.forEach(input => {
                    const key = input.dataset.storageKey;
                    if (!key) return;

                    // 实时保存事件
                    input.addEventListener('input', function () {
                        const currentData = getPersistData();
                        currentData[key] = this.value;
                        savePersistData(currentData);
                    });

                    console.log('已绑定事件:', key, input);
                });

                // 只绑定一次 beforeunload 事件(避免重复绑定)
                window.removeEventListener('beforeunload', handleBeforeUnload);
                window.addEventListener('beforeunload', handleBeforeUnload);
            }

            // 执行初始化
            restoreInputValues();
            bindInputEvents();
        }

        // 执行计算函数
        function executeCalculations() {
            for (let i = 0; i < 5; i++) {
                // 检查函数是否存在,避免报错
                if (typeof dan_xiang_jia_ge_ji_suan === 'function') {
                    dan_xiang_jia_ge_ji_suan(i);
                } else {
                    console.error('dan_xiang_jia_ge_ji_suan 函数未定义');
                }
            }
        }

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', function () {
            // 初始化持久化输入框
            initPersistInputs();

            // 执行计算
            executeCalculations();
        });
    </script>
</body>
</html>
© 版权声明

相关文章

暂无评论

none
暂无评论...