• luckysheet的一点使用心得


    如何使用

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <style>
            #luckysheet {
                width: 100%;
                height: 600px;
            }
        style>
    
        <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/css/pluginsCss.css' />
        <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/plugins.css' />
        <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/css/luckysheet.css' />
        <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/assets/iconfont/iconfont.css' />
        <script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/js/plugin.js">script>
        <script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js">script>
    head>
    
    <body>
    	<div id="luckysheet">div>
    body>
    
    <script>
     luckysheet.create()
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述


    初始化时写入默认数据

       luckysheet.create({
            container: 'luckysheet', // luckysheet为容器id
            lang: 'zh',              // 设定表格语言
            data: [
                {
                    name: '工作表名称',
                    row: 30,                 // 行数
                    column: 30,              // 列数
                    // defaultRowHeight: 19, // 自定义行高
                    // defaultColWidth: 73,  // 自定义列宽
                    // 初始化使用的单元格数据
                    celldata: [
                        {
                            r: '0',
                            c: '1',
                            v: {
                                m: 'img \r\n 555 123',
                                v: 'img \r\n 555 123',
                                fc: '#ff0000',
                                tb: 2,  // 内容超出自动换行
                            }
                        },
                        {
                            r: '0',
                            c: '3',
                            v: {
                                m: 'rq',
                                v: 'rq',
                            }
                        },
                        {
                            r: '0',
                            c: '5',
                            v: {
                                m: 'rq',
                                v: 'rq',
                            }
                        },
                        {
                            r: '3',
                            c: '5',
                            v: {
                                m: 'img',
                                v: 'img',
                            }
                        }
                    ]
                }
            ],
        });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    根据内容查找格子

    function search() {
        console.log(luckysheet.find("rq")); // 返回数组
    }
    
    • 1
    • 2
    • 3

    设置所有单元格文字自动换行

    // 设置所有单元格自动换行
    // 需要先设置换行,再写入值,才有效果。先设置值,再设置换行,没有效果
    function setTextWrap() {
        const rowNum = allSheetData.length;    // 表格行数
        const colNum = allSheetData[0].length; // 表格列数
    
        for (let _row = 0; _row < rowNum; _row++) {
            for (let _col = 0; _col < colNum; _col++) {
                luckysheet.setCellValue(_row, _col, {
                    tb: 2,
                    // bg: "#FF0000"
                }, {
                    // 是否刷新界面,默认true,多单元格赋值时控制节流,前面单元格置为false,最后一个单一个置为true
                    isRefresh: _row === rowNum - 1 && _col === colNum - 1,
                    success: () => {}
                })
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    替换格子的内容

    // 替换格子内容
    function replace() {
        range = luckysheet.getRange(); // 存放原来的选中区域
    
        luckysheet.find("rq").forEach(({ row, column }, index, arr) => {
            luckysheet.setCellValue(row, column, {
                  m: '2020- \r\n 星期日',
                  v: '2020- \r\n 星期日',
                  tb: 2,
                  isRefresh: true, // 是否刷新界面,默认true,多单元格赋值时控制节流,前面单元格置为false,最后一个单一个置为true
            }, {
                success: () => {
                    // 先选中
                    luckysheet.setRangeShow({ row:[row], column:[column] });
    
                    // 再进入编辑模式,让换行生效
                    luckysheet.enterEditMode({
                        success: () => {
                            if (index === arr.length - 1) {
                                // 退出编辑模式
                                luckysheet.exitEditMode();
    
                                // 选中替换前的选区
                                luckysheet.setRangeShow({ row: range[0].row, column: range[0].column })
                            }
                        }
                    });
                }
            });
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    插入图片

    function insertImage() {
    /** @desc mc是合并单元格后的数据 */
    luckysheet.find("img").forEach(({ row, column, mc }) => {
        const cellWidth = luckysheet.getColumnWidth([column])[column];
        const cellHeight = luckysheet.getRowHeight([row])[row];
    
        let img = new Image();
        img.src = './demo.jpg';
        img.width = cellWidth * (mc?.cs || 1);
        img.height = cellHeight * (mc?.rs || 1);
    
        img.onload = function () {
            let canvas = document.createElement('canvas');
            canvas.width = this.width;
            canvas.height = this.height;
            const context = canvas.getContext('2d');
            context.drawImage(img, 0, 0, this.width, this.height);
            const dataUrl = canvas.toDataURL("image/png");
    
            luckysheet.clearCell(row, column);
            luckysheet.insertImage(dataUrl, {
                order: 0,
                rowIndex: row,
                colIndex: column,
                success: () => {
                    // 【源代码】src/controllers/imageCtrl.js:677 fixme  插入图片 宽/高内部设置为400
                }
            });
        }
    })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    源代码中,插入图片时,图片的默认展示尺寸为宽/高400,需要点击图片,选择恢复原图,才是图片的真实宽高。

    我的需求时,插入的图片根据格子的大小,自动填满整个格子。所以我把src/controllers/imageCtrl.js:677的代码改了,打包后,项目引用本地文件

    修改后的代码

    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/css/pluginsCss.css' />
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/plugins.css' />
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/css/luckysheet.css' />
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/assets/iconfont/iconfont.css' />
    
    
    <script src="plugin.js">script>
    <script src="luckysheet.umd.js">script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    获取表格的配置和数据

    function getConfig() {
        console.log(luckysheet.getAllSheets());
    }
    
    • 1
    • 2
    • 3

    文字换行不生效

    初始化数据或者用方法修改内容,内容中含有换行符,页面的格子没有换行,需要双击格子,进入编辑模式,换行才会生效。

    我的解决方法:表格创建后,查找含有换行符的格子,逐个进入编辑模式,然后退出编辑模式

    luckysheet.create({
            container: 'luckysheet', // luckysheet为容器id
            lang: 'zh',              // 设定表格语言
            data: [
                {
                    name: '工作表名称',
                    row: 30,                 // 行数
                    column: 30,              // 列数
                    // defaultRowHeight: 19, // 自定义行高
                    // defaultColWidth: 73,  // 自定义列宽
                    // 初始化使用的单元格数据
                    celldata: [
                        {
                            r: '0',
                            c: '1',
                            v: {
                                m: 'img \r\n 555 123',
                                v: 'img \r\n 555 123',
                                fc: '#ff0000',
                                tb: 2, // 内容超出自动换行
                            }
                        },
                        {
                            r: '0',
                            c: '3',
                            v: {
                                m: 'rq',
                                v: 'rq',
                            }
                        },
                        {
                            r: '0',
                            c: '5',
                            v: {
                                m: 'rq',
                                v: 'rq',
                            }
                        },
                        {
                            r: '3',
                            c: '5',
                            v: {
                                m: 'img',
                                v: 'img',
                            }
                        }
                    ]
                }
            ],
            hook: {
                // 表格创建之后触发
                workbookCreateAfter:function(allConfig){
                    console.log(allConfig);
    
                    luckysheet.find("\n").forEach(({ row, column }, index, arr) => {
                        luckysheet.setRangeShow({ row:[row], column:[column] }, {
                            success: () => {
                                // 进入编辑模式,让换行生效
                                luckysheet.enterEditMode({
                                    success: () => {
                                        if (index === arr.length - 1) {
                                            // 退出编辑模式
                                            luckysheet.exitEditMode();
    
                                            // 选中第一个格子
                                            luckysheet.setRangeShow({ row:[0], column:[0] }, {
                                                show: false, // 选中状态不要高亮
                                            })
                                        }
                                    }
                                });
                            }
                        })
                    });
    
                    allSheetData = luckysheet.getSheetData();
                }
            }
        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    根据后端数据填写表格

    // 写入表格数据
        setData () {
          const { excelData } = this;
          let setCount = 0;
    
          Object.keys(excelData).forEach((key) => {
            luckysheet.find(key, {
              type: 'v',            // 查找原始值,替换显示值,后期可以重复更新
              // isWholeWord: true, // 整词匹配,避免匹配到其它的格子 有合并格子会报错
            })
              .filter(fItem => fItem.v === key) // 因为整词匹配遇到合并格子会报错,所以在结果里过滤原始值全等的项
              .forEach(({ row, column }) => {
    
              setCount += 1
    
              if (excelData[key].startsWith('http')) {
                const img = new Image()
                img.setAttribute('crossOrigin', 'anonymous')
                img.src = excelData[key]
                img.width = '200'
                img.height = '200'
    
                img.onload = () => {
                  let canvas = document.createElement('canvas')
                  canvas.width = img.width
                  canvas.height = img.height
                  const context = canvas.getContext('2d')
                  context.drawImage(img, 0, 0, img.width, img.height)
                  const quality = 0.8
                  const dataUrl = canvas.toDataURL('image/png', quality)
    
                  luckysheet.setCellValue(row, column, { m: '' }, {
                    success: () => {
                      luckysheet.insertImage(dataUrl, {
                        rowIndex: row,
                        colIndex: column,
                        success: () => {
                          setCount--
                          this.getShot(setCount)
                        }
                      })
                    }
                  });
                }
    
                return
              }
    
              luckysheet.setCellValue(row, column, {
                m: excelData[key], // 设置显示值
                v: excelData[key], // 设置显示值
    
                // 设置为纯文本模式,避免设置日期 e.g. 2020-08-29时,编辑模式弹出个日期选择器
                ct: {
                  fa: "@",
                  t: "s"
                },
                // tb: 2,   // 文本超出格子,自动换行。自动编辑模式撑开高度时,高度会变得很高
                ht: 1,      // 文字左对齐
              }, {
                success: () => {
                  // 先选中
                  luckysheet.setRangeShow({ row:[row], column:[column] });
    
                  // 再进入编辑模式,让换行生效,默认值v才能撑开格子
                  luckysheet.enterEditMode({
                    success: () => {
                      // 退出编辑模式
                      luckysheet.exitEditMode();
    
                      setCount--
                      this.getShot(setCount)
                    }
                  });
                }
              })
            })
          })
        },
    
        /**
         * 获取表格图片
         * @params setCount 正在进行赋值操作的格子数
         * */
        getShot(setCount) {
          if (setCount > 0) {
            return;
          }
    
          const sheetData = luckysheet.getSheetData();
          luckysheet.setRangeShow({ row: [0, sheetData.length - 1], column: [0, sheetData[0].length - 1] }, {
              success: () => {
                const shot = luckysheet.getScreenshot({ row: [0, sheetData.length - 1], column: [0, sheetData[0].length - 1] });
    
                this.url = shot
              }
            }
          )
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

    表格截图

    要选中表格区域,才能截图
    正常情况,截图里没有出现你插入的图片

     const sheetData = luckysheet.getSheetData();
          luckysheet.setRangeShow({ row: [0, sheetData.length - 1], column: [0, sheetData[0].length - 1] }, {
              success: () => {
                const shot = luckysheet.getScreenshot({ row: [0, sheetData.length - 1], column: [0, sheetData[0].length - 1] });
    
                this.url = shot
              }
            }
          )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    表格截图2

    先把能截出来的底图画在canvas上,然后遍历图片信息,再上一步的基础上把图片加上去
    我遇到的问题是,图片位置不能对在格子上,会出现偏移,无解

     // 表格截图
        // 获取表格图片
        function getShot() {
            luckysheet.setRangeShow({ row: [0, allSheetData.length - 1], column: [0, allSheetData[0].length - 1] }, {
                    success: () => {
                        const shot = luckysheet.getScreenshot({ row: [0, allSheetData.length - 1], column: [0, allSheetData[0].length - 1] });
                        let { ch_width, rh_height, images = {} } = luckysheet.getAllSheets()[0];
    
                        if (Object.keys(images).length) {
                            let canvas = document.createElement('canvas');
                            canvas.width = ch_width;
                            canvas.height = rh_height;
                            const context = canvas.getContext('2d');
    
                            const img = new Image();
                            img.src = shot;
                            img.width = ch_width;
                            img.height = rh_height;
    
                            img.onload = function () {
                                context.drawImage(img, 0, 0, this.width, this.height);
                                const dataUrl = canvas.toDataURL("image/png");
    
                                Object.values(images).forEach((image, index, arr) => {
                                    const img = new Image();
                                    img.src = image.src;
                                    img.width = image.originWidth;
                                    img.height = image.originHeight;
    
                                    img.onload = function () {
                                        context.drawImage(img, image.default.left, image.default.top, this.width, this.height);
    
                                        if (index === arr.length - 1) {
                                            const dataUrl = canvas.toDataURL("image/png");
                                        }
                                    }
                                })
                            };
                        }
                    }
                }
            )
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    打印

    import printJS from "print-js";
       
    // 打印
        handlePrint() {
          if (!this.url) {
            console.error('没有图片');
            return;
          }
    
          printJS(
            {
              printable: this.url,
              type: 'image',
              documentTitle: '表格名称'
            }
          )
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    根据后端配置,初始化表格

        // 加载表格
        loadSheet() {
          luckysheet.create({
            ...this.sheetOptions, // 后端返回的一些通用配置、格子数据
            showtoolbarConfig: {},
            enableAddRow: false,
            enableAddBackTop: false,
          })
    
          // 获取表格数据,然后通过上面表格初始化填上的key,进行替换操作
          this.getExcelData();
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    导出PDF

    主要是对上面截图的导出

    import jsPDF from 'jspdf';
    import html2canvas from 'html2canvas'
    
     // 导出表格数据
        async exportTableData() {
          this.$message('导出中...');
    
          setTimeout(() => {
            const element = document.querySelector(".el-image > img");
            // window.pageYOffset = 0;
            // document.documentElement.scrollTop = 0
            // document.body.scrollTop = 0
            html2canvas(element,{
              // height: node.offsetHeight,
              allowTaint: true,
              // allowTaint: true,
              logging:true,
              scale: 2 // 提升画面质量,但是会增加文件大小
            }).then(function (canvas) {
              var contentWidth = canvas.width;
              var contentHeight = canvas.height;
              //一页pdf显示html页面生成的canvas高度;
              var pageHeight = contentWidth / 592.28 * 841.89;
              //未生成pdf的html页面高度
              var leftHeight = contentHeight;
              //页面偏移
              var position = 0;
              //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
              var imgWidth = 595.28;
              var imgHeight = 592.28 / contentWidth * contentHeight;
    
              var pageData = canvas.toDataURL('image/jpeg', 1.0);
    
              var pdf = new jsPDF('', 'pt', 'a4');
    
              //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
              //当内容未超过pdf一页显示的范围,无需分页
              if (leftHeight < pageHeight) {
                pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
              } else {    // 分页
                while (leftHeight > 0) {
                  pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
                  leftHeight -= pageHeight;
                  position -= 841.89;
                  //避免添加空白页
                  if (leftHeight > 0) {
                    pdf.addPage();
                  }
                }
              }
              pdf.setFont('simsun');
              pdf.save('记录.pdf');
            });
          }, 1000)
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    静默用表格填充数据,然后获取图片

    需要把结构渲染出来,然后沉到文档下面来隐藏,不然我手动触发格子的编辑模式来撑开格子位置就不能生效

        <div class="imgBox" v-else  v-show="true">
            <el-image
              :src="url"
              :preview-src-list="[url]"
            />
          div>
    
          
          <div class="sheet-container" style="z-index: -1">
            <div class="print_content" id="luckysheet" />
          div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
       .sheet-container {
          width: 100%;
          height: 500px;
          position: relative;
    
          .print_content {
            width: 100%;
            height: 100%;
          }
        }
    
        .imgBox {
          height: calc(100% - 80px);
          overflow: auto;
          .scroll-bar();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    测试相关代码

    github

  • 相关阅读:
    为什么JWT要结合Redis使用
    软件测试100天上岸2-测试必须有策略
    dart包的创建
    Fourier傅里叶变换的线性性质和位移性质
    Python | mkvirtualenv命令改变虚拟环境存储位置
    数据集MNIST手写体识别 pyqt5+Pytorch/TensorFlow
    微服务--Gatway:网关
    LeetCode:1929.数组串联
    解决方法:Ubuntu 22.04网络无法连接,没有网络图标
    搜狗反链量查询易语言代码
  • 原文地址:https://blog.csdn.net/weixin_44240581/article/details/126337964