如何使用

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><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>

初始化时写入默认数据

   luckysheet.create({container: 'luckysheet', // luckysheet为容器idlang: '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',}}]}],});

根据内容查找格子

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

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

// 设置所有单元格自动换行
// 需要先设置换行,再写入值,才有效果。先设置值,再设置换行,没有效果
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,最后一个单一个置为trueisRefresh: _row === rowNum - 1 && _col === colNum - 1,success: () => {}})}}
}

替换格子的内容

// 替换格子内容
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 })}}});}});})
}

插入图片

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}});}
})
}

源代码中,插入图片时,图片的默认展示尺寸为宽/高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="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>-->
<script src="plugin.js"></script>
<script src="luckysheet.umd.js"></script>

获取表格的配置和数据

function getConfig() {console.log(luckysheet.getAllSheets());
}

文字换行不生效

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

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

luckysheet.create({container: 'luckysheet', // luckysheet为容器idlang: '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();}}});

根据后端数据填写表格

// 写入表格数据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 += 1if (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.widthcanvas.height = img.heightconst context = canvas.getContext('2d')context.drawImage(img, 0, 0, img.width, img.height)const quality = 0.8const 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}})},

表格截图(没有插入图片)

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

 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}})

表格截图(有插入图片)

先把能截出来的底图画在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");}}})};}}})}

打印

import printJS from "print-js";// 打印handlePrint() {if (!this.url) {console.error('没有图片');return;}printJS({printable: this.url,type: 'image',documentTitle: '表格名称',style: '@page{size:auto;margin: 0cm 1cm 0cm 1cm;}' // 去除页眉页脚})},

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

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

导出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 = 0html2canvas(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)},

隐藏表格,获取截图

需要把结构渲染出来,然后设置为不可见,不然我手动触发格子的编辑模式来撑开格子位置就不能生效

    <div class="imgBox" v-else  v-show="true"><el-image:src="url":preview-src-list="[url]"/></div><!-- 要展示在页面上,撑开后截图才能生效,调试时打开zIndex --><div class="sheet-container" style="z-index: -1"><div class="print_content" id="luckysheet" /></div>
   .sheet-container {width: 100%;height: 500px;position: relative;.print_content {width: 100%;height: 100%;}}.imgBox {height: calc(100% - 80px);overflow: auto;}

测试相关代码

【github】

实际使用出现的问题

换行生效后,格子高度被撑高

表格已经设置了行高,进入编辑模式,让换行生效后退出,格子高度会变高

originSheetOptions: {}, // 表格信息和配置,存储第一次的配置,不会改变sheetOptions: {},       // 表格信息和配置,操作表格,里面的数据会变// opt是后台接口返回的表格数据和配置// 换行后格子高度会变化,数据也会被修改,所以要把原始的配置存起来,用来做修复// cloneDeep是深拷贝,避免数据污染this.originSheetOptions = cloneDeep(opt);this.sheetOptions = cloneDeep(opt);// 加载表格loadSheet() {luckysheet.create({...this.sheetOptions,// showtoolbarConfig: {},// enableAddRow: false,// enableAddBackTop: false,})// 获取真实数据,替换表格的占位内容this.getExcelData();}// 一系列操作,如,替换占位内容,插入图片等// 重新设置行高,修复格子高度变高的问题fixRowHeight() {const rowHeight = this.originSheetOptions.data[0].config.rowlen;return new Promise(resolve => {luckysheet.setRowHeight(rowHeight, {success: () => {resolve()}});})},

换行后,文字的样式丢失

文字样式如:字体大小,字体颜色等

 const findItems = luckysheet.find(key, {type: 'v',            // 查找原始值,替换显示值,后期可以重复更新// isWholeWord: true, // 整词匹配,避免匹配到其它的格子 有合并格子会报错}).filter(fItem => fItem.v === key); // 因为整词匹配遇到合并格子会报错,所以在结果里过滤原始值全等的项findItems.forEach(({ row, column, ...args }, cellIndex, cellArr) => {}luckysheet.setCellValue(row, column, {m: excelData[key], // 设置显示值v: excelData[key], // 设置原始值}, {success: () => {// 先选中luckysheet.setRangeShow({ row:[row], column:[column] });// 再进入编辑模式,让换行生效,默认值v才能撑开格子luckysheet.enterEditMode({success: () => {// 退出编辑模式luckysheet.exitEditMode({success: () => {// 当setCellValue的值存在换行符,同时用编辑模式来让换行生效后,所在格子的v、m属性会被删除,后续无法通过luckysheet.find找到格子// v的值会被移动到 格子.ct.s[0].v 里面// 和文字相关的属性如ff(字体),还在原来的位置,如格子.ff,造成文字相关的样式丢失,所以需要把格子.文字相关样式 移动到 格子.ct.s[0]里面const rangeValue = luckysheet.getRangeValuesWithFlatte();if (rangeValue[0].ct.s) {const { ff, fs, fc, bl, it, cl, un } = args;rangeValue[0].ct.s[0] = {...rangeValue[0].ct.s[0],ff, // 字体fs, // 字体大小fc, // 字体颜色bl, // 粗体it, // 斜体cl, // 删除线un, // 下划线}}...}});}});}})

获取的截图有点模糊

// 修改表格配置
opt.devicePixelRatio = 4; // 避免导出图片模糊

插入单元格的图片位置偏移

// 修改表格配置
opt.zoomRatio = 1; // 避免插入图片偏移

出现的原因是
保存配置时,表格是缩放到80%的
重新加载表格时,表格读取配置,显示为80%
这时往指定单元格插入图片时,就会出现偏移
需要在加载表格前,把缩放比例配置设为100%,再进行插入

luckysheet的一点使用心得相关推荐

  1. 我的一点自学心得[摘]

    我的一点学习心得[强烈推荐给新手](转) 我的一点自学心得[转帖](强烈推荐给新手) 在网上常看到朋友问很多有关于数学学习的问题,有数学系的,也有纯自学的,许多问题我都亲身经历过.在这里就简单说一下我 ...

  2. 吴恩达ex3_Andrew Ng在Coursera上课程ex3的一点小心得

    Andrew Ng在Coursera上课程ex3的一点小心得 (2012-09-16 11:20:38) ex3中第三问要求用logistic regression来进行预测,第四问用神经网络算法进行 ...

  3. 运营电影网站的一点个人心得

    电影网站盈利比较简单而且要建一个电影网站也比较容易,因此我们很多 站长朋友们把目光投到电影网站上面来.网站是建好了可是却不像当初想象的那样能够轻松盈利,今天和大家分享自己运营电影网站的一点小心得,希望 ...

  4. 南开02-06经济学考研真题和我的一点考研心得

    <script type="text/javascript">ad_01.innerHTML=span_ad_01.innerHTML;span_ad_01.inner ...

  5. 关于网站更新速度的一点小心得

    网上看过很多关于网站优化的文章,其中很多都提到了网站的更新问题.大部分的结论是网站更新速度越快越好.但是在维护我自己的网站的时候,我却发现这个结论并不是完全正确. 我的网站:114社区网 [url]h ...

  6. 多线程编程的一点小心得(1)

    最近有了很多想法,想把我用过的东西都吃透,这样才不会变成所谓的"样样通样样松".我是新手,老鸟请飘过,当然,这篇小心得如果有什么毛病,还请指出来.先行谢过! 其实我本来想把博客当作 ...

  7. 408计算机先学哪个,我的一点初试心得(主要讲讲408怎么复习)

    前段时间写了复试贴,初试贴想写但内心不平静一直没写,风华哥让新版主们分享初复试经验和心得,就写写自己的一点心得吧.说到初试经验我很惭愧,我不是那种踏实的搞时间战的学霸,我正式准备是从8月份,考的也不太 ...

  8. 惠普JAVA工程师给想从事JAVA开发的朋友一点工作心得

    工作已经有段时间了,突然想写点东西,大学的时候就有写日记的习惯,但是自从进入惠普工作,慢慢的也没有时间去写日记,希望通过这篇文章能让学弟学妹们看了有所帮助. 相信很多同学很我一样大四的时候都比较迷茫, ...

  9. 对于scanf的使用一点体会心得

    今天非常的突发气象的在acm上面做了一下题目,悲剧的是多年不用c的人忘记了怎么样的使用scanf了,今天还学到了一点东西. 题目里面提示了输入两个数,规定第1-6列是第一个数的范围,第8-9列是第二个 ...

最新文章

  1. 2022-2028年中国女式西装行业研究及前瞻分析报告
  2. 不能定义声明dllimport_C#:多个声明的一个属性(DLLImport)
  3. 认识ASP.NET配置文件Web.config
  4. 【 Linux 】记录下第一次使linux系统遇到的问题(系统安装、配置查看、搜狗输入法安装)
  5. 红帽技术开放日:参与开源社区不只有贡献代码这一种方式
  6. 性能分析工具 Android TraceView
  7. 浮点数相加php,利用php怎么实现一个浮点数精确运算功能
  8. who is the one who actually know the essential things in life?
  9. VS 之 InstallShield Limited Edition for Visual Studio 2015 图文教程
  10. YbtOJ#482-爬上山顶【凸壳,链表】
  11. iOS - 判断用户是否允许推送通知(iOS7/iOS8)
  12. 软件测试和python那个号_软件测试:Java VS Python
  13. 开源软件 | 深度学习用于道路病害检测
  14. [译]R语言——Shiny框架之构建(一):1.结构——1.独立应用程序——1.应用的格式和启动
  15. 使用QT + cocos2dx制作工具
  16. Race Condition是什么
  17. 图书管理系统(个人)
  18. 【Tools系列】推荐一款好用的截图工具:Snipaste
  19. 【Oracle】Oracle分析函数详解
  20. 芭蕉树上第十二根芭蕉--opencv配置问题

热门文章

  1. 利用赛门铁克Symantec Endpoint Protection漏洞渗透企业网络
  2. 苏宁智慧零售燃爆,818发烧节成比肩阿里双11的两大消费高峰
  3. ubuntu nvidia独显和intel集显切换
  4. SQL临时表|游标|两个日期之间计算时差|临时表条件查询
  5. 打印机故障检测(CANON)
  6. 【洛谷P4997】不围棋【并查集】【模拟】
  7. win版敬业签怎么通过便签快捷键对便签内容执行标记已完成操作?
  8. 明修栈道,暗渡陈仓----之私募一哥徐翔新玩法 z
  9. 中国飙升金牌榜第一,奥运赛事,不止是惊心动魄……
  10. 卡内基梅隆大学梁俊卫:视频中行人的多种未来轨迹预测