1.下载Luckysheet源码
下载地址:https://github.com/dream-num/Luckysheet
按照下载地址提示 npm run build 打包源码,生成dist文件夹
2.引入luckysheet的js文件和css文件
① 在vue项目的根目录public中新建luckysheet文件夹,然后将步骤1中的dist内的所有文件放到luckysheet中。
② 在vue项目的根目录public的index.html文件中引入相关js和css
<link rel='stylesheet' href='./luckyexcel/plugins/css/pluginsCss.css' />
<link rel='stylesheet' href='./luckyexcel/plugins/css/pluginsCss.css' />
<link rel='stylesheet' href='./luckyexcel/plugins/plugins.css' />
<link rel='stylesheet' href='./luckyexcel/css/luckysheet.css' />
<link rel='stylesheet' href='./luckyexcel/assets/iconfont/iconfont.css' />
<script src="./luckyexcel/plugins/js/plugin.js"></script>
<script src="./luckyexcel/luckysheet.umd.js"></script>
③ 验证是否成功引入js和css
参考文件:https://blog.csdn.net/Lyy1991Wdl/article/details/124175868 进行验证
或者直接使用下面的代码:
<template>
<div class="luckyexcelConstentCss" :style="{height}">
<div id="luckysheet" class="luckyexcelCss" />
</div>
</template>
<script>
export default {
props: {
height: {
type: String,
default: '500px'
}
},
mounted() {
this.init()
},
methods: {
init() {
const options = {
container: 'luckysheet', // 设定DOM容器的id
title: 'Luckysheet Demo', // 设定表格名称
lang: 'zh', // 设定表格语言
plugins: ['chart'], // 图表插件使用 https://blog.csdn.net/u013355529/article/details/116133127
showtoolbar: false, // 想要使用 showtoolbarConfig, 必须将showtoolbar设为false
showtoolbarConfig: {
undoRedo: true, //撤销重做,注意撤消重做是两个按钮,由这一个配置决定显示还是隐藏
mergeCell: true, // '合并单元格'
fillColor: true, // '单元格颜色'
textColor: true, // '文本颜色'
sortAndFilter: true, // '排序和筛选'
findAndReplace: true, // '查找替换'
chart: true, // 图表 (引入插件: https://blog.csdn.net/u013355529/article/details/116133127)
print: true // '打印'
}
}
luckysheet.create(options) // eslint-disable-line
}
}
}
</script>
<style scoped>
.luckyexcelConstentCss {
margin: 0 30px;
}
.luckyexcelCss {
width: 100%;
height: 100%;
}
</style>
vue项目运行之后显示以下界面即引入成功
3.引入图表chartmix
将步骤1中的dist内的expendPlugins文件夹,放置到你的vue项目的根目录public中
验证图表插件是否引入成功
在表格中输入以下内容,并将输入的内容选中,然后点击图表按钮
引入成功则显示以下样式
4.实现打印按钮功能
参考文献:https://blog.csdn.net/alan_ji198573/article/details/128624832
回到步骤1下载的luckysheet源码
① 找到lucksheet源码中\src\controllers\menuButton.js,修改函数:$(“#luckysheet-icon-print”).click
将 $(“#luckysheet-icon-print”).click 函数的内容用以下代码替换掉
//print
$("#luckysheet-icon-print").click(function(){
//获取页面的按钮控件,在点击菜单时触发页面按钮点击事件
if($("#printPreviewBtn"))
{
$("#printPreviewBtn").click();
}
//将源项目代码全部注释,只用上面的代码
}
② 新增getScreenshotNew函数,找到luckysheet源码中的src\global\api.js
新增getScreenshotNew函数,即将以下代码复制到api.js中
/**
* 将选中区域进行截图,截图完成后调用指定委托函数,(修复支持插入的图片及图表截图):ALAN-JI
* @param {Object} options 可选参数
* @param {Object | String} options.range 选区范围,只能为单个选区;默认为当前选区
* @param {function} action 委托执行函数,当所有绘图完成后,执行此委托函数(委托函数中可用于触发图片打印,或图片显示)
*/
export function getScreenshotNew(action, options = {}) {
let {
range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1],
} = { ...options }
if (getObjType(range) == 'string') {
if (!formula.iscelldata(range)) {
return tooltip.info("The range parameter is invalid.", "");
}
let cellrange = formula.getcellrange(range);
range = {
"row": cellrange.row,
"column": cellrange.column
};
}
if (getObjType(range) != 'object' || range.row == null || range.column == null) {
return tooltip.info("The range parameter is invalid.", "");
}
let str = range.row[0],
edr = range.row[1],
stc = range.column[0],
edc = range.column[1];
let has_PartMC = hasPartMC(Store.config, str, edr, stc, edc);
if (has_PartMC) {
return tooltip.info('Cannot perform this operation on partially merged cells', '');
}
let visibledatarow = Store.visibledatarow;
let visibledatacolumn = Store.visibledatacolumn;
let scrollHeight, rh_height;
if (str - 1 < 0) {
scrollHeight = 0;
rh_height = visibledatarow[edr];
}
else {
scrollHeight = visibledatarow[str - 1];
rh_height = visibledatarow[edr] - visibledatarow[str - 1];
}
//根据当前分辨率计算出A4纸宽度,高度(高度不用限制,默认会自动分页)
let a4Size=calculateA4PaperSize();
let scrollWidth, ch_width=a4Size.width;
if (stc - 1 < 0) {
scrollWidth = 0;
ch_width = visibledatacolumn[edc]<a4Size.width ? visibledatacolumn[edc]:a4Size.width;
}
else {
scrollWidth = visibledatacolumn[stc - 1];
ch_width = visibledatacolumn[edc] - visibledatacolumn[stc - 1]<a4Size.width ? visibledatacolumn[edc] - visibledatacolumn[stc - 1]:a4Size.width;
}
let newCanvas = $("<canvas>").attr({
width: Math.ceil(ch_width * Store.devicePixelRatio),
height: Math.ceil(rh_height * Store.devicePixelRatio)
}).css({ width: ch_width, height: rh_height });
luckysheetDrawMain(scrollWidth, scrollHeight, ch_width, rh_height, 1, 1, null, null, newCanvas);
let ctx_newCanvas = newCanvas.get(0).getContext("2d");
//补上 左边框和上边框
ctx_newCanvas.beginPath();
ctx_newCanvas.moveTo(
0,
0
);
ctx_newCanvas.lineTo(
0,
Store.devicePixelRatio * rh_height
);
ctx_newCanvas.lineWidth = Store.devicePixelRatio * 2;
ctx_newCanvas.strokeStyle = luckysheetdefaultstyle.strokeStyle;
ctx_newCanvas.stroke();
ctx_newCanvas.closePath();
ctx_newCanvas.beginPath();
ctx_newCanvas.moveTo(
0,
0
);
ctx_newCanvas.lineTo(
Store.devicePixelRatio * ch_width,
0
);
ctx_newCanvas.lineWidth = Store.devicePixelRatio * 2;
ctx_newCanvas.strokeStyle = luckysheetdefaultstyle.strokeStyle;
ctx_newCanvas.stroke();
ctx_newCanvas.closePath();
//获取插入图片的元素,并在canvas上进行绘制
if ($('#luckysheet-image-showBoxs')) {
var imgs = $('#luckysheet-image-showBoxs img');
imgs.each(function (i) {
var parent = $(this).parent().parent();
var left = parent.css("left").replace('px', '');
var top = parent.css("top").replace('px', '');
var width = parent.css("width").replace('px', '');
var height = parent.css("height").replace('px', '');
var img = new Image()
img.src = $(this).attr("src");
ctx_newCanvas.drawImage(img, left, top, width, height);
});
}
//获取统计图元素,并在canvas上进行绘制
let targetDoms = document.querySelectorAll('.luckysheet-modal-dialog.luckysheet-modal-dialog-chart.luckysheet-data-visualization-chart');
var chartCount = 0;
if (targetDoms && targetDoms.length > 0)
{
repaintChartScreenshot(newCanvas,ctx_newCanvas,targetDoms,action,0,targetDoms.length);
}
if (!targetDoms || targetDoms.length == 0) {
if (action) {
action(newCanvas.get(0).toDataURL("image/png", 1));
}
}
}
/**
* 递归获取所有统计图,并重绘chart到截屏图上:ALAN-JI
* @param {object} newCanvas canvas画布元素对象
* @param {object} ctx_newCanvas 当前画布用于绘制新图的对象
* @param {NodeListOf} targetDoms 所有统计图Nodes集合
* @param {function} action 委托函数,当所有绘图完成后,执行此委托函数(委托函数中可用于触发图片打印,或图片显示)
* @param {int} index 当前统计图下标
* @param {int} length 统计图总集合长度
*/
export function repaintChartScreenshot(newCanvas,ctx_newCanvas,targetDoms,action,index,length) {
let targetDom = targetDoms[index];
var left = targetDom.style.left.replace('px', '');
var top = targetDom.style.top.replace('px', '');
var width = targetDom.style.width.replace('px', '');
var height = targetDom.style.height.replace('px', '');
// 此处是实现滚动元素长截图的关键 start
let copyDom = targetDom.cloneNode(true)
copyDom.setAttribute('id', 'copyDom') // 更改id 避免与targetDom id重复
copyDom.style.width = targetDom.scrollWidth + 'px'
copyDom.style.height = targetDom.scrollHeight + 'px'
var chartCanvas = targetDom.getElementsByTagName("canvas")[0];
var canvasToImg = new Image();
canvasToImg.src = chartCanvas.toDataURL('image/png', 1);
canvasToImg.style = chartCanvas.style;
copyDom.innerHTML = copyDom.innerHTML.replace(chartCanvas.outerHTML, canvasToImg.outerHTML)
copyDom.style.zIndex=-50
document.querySelector('body').appendChild(copyDom);
// 此处是实现滚动元素长截图的关键 end
/*
*如不需要长截图,或者要截取的元素无滚动即完全显示。
*下方要截取的元素改为targetDom,并把copyDom相关代码删除即可
*/
// html2canvas截屏,屏幕有滚动条时截图为空
html2canvas(copyDom, {
backgroundColor: "transparent",
allowTaint: true,
useCORS: true,
scale: window.devicePixelRatio * 3,
logging: false,
imageTimeout: 15000,
removeContainer: true,
}).then(canvas => {
var chartImg = new Image()
chartImg.src = canvas.toDataURL('image/png', 1);
document.querySelector('body').removeChild(copyDom)
chartImg.onload = function () {
index++;
ctx_newCanvas.drawImage(chartImg, left, top, width, height);
if (index >= length && action) {
action(newCanvas.get(0).toDataURL("image/png", 1));
}
else
{
//递归调用重绘图片
repaintChartScreenshot(newCanvas,ctx_newCanvas,targetDoms,action,index,length);
}
}
});
}
/**
* 根据当前系统DPI象素计算A4纸大小:ALAN-JI
* @returns {object} width:a4宽度,height:a4高度
*/
export function calculateA4PaperSize()
{
function findFirstPositive(b, a, i, c) {
c=(d,e)=>e>=d?(a=d+(e-d)/2,0<b(a)&&(a==d||0>=b(a-1))?a:0>=b(a)?c(a+1,e):c(d,a-1)):-1
for (i = 1; 0 >= b(i);) i *= 2
return c(i / 2, i)|0
}
var dpi = findFirstPositive(x => matchMedia(`(max-resolution: ${x}dpi)`).matches)
switch (dpi) {
case 72:
return { width: 598, height: 842 };
case 96:
return { width: 794, height: 1123 };
case 120:
return { width: 1487, height: 2105 };
case 150:
return { width: 1240, height: 1754 };
case 300:
return { width: 2480, height: 3508 };
default:
return { width: 794, height: 1123 };
}
}
③ 依次重复步骤1和步骤2,然后vue项目中使用 npm install vue-print-nb -D 引入 vue-print-nb 打印插件
④ 可以使用以下vue完整代码到vue项目中,测试是否打印成功
<template>
<div class="luckyexcelConstentCss" :style="{height}">
<el-button id="printPreviewBtn" style="display: none;" @click="printExcel()">打印预览</el-button>
<el-button id="printExcelBtn" style="display: none;" plain
v-print="{ id: 'print_html', popTitle: 'test111' }">打印</el-button>
<div id="print_html" class="procedure" style="text-align: center;z-index: 0;"></div>
<div id="luckysheet" class="luckyexcelCss" />
</div>
</template>
<script>
import Vue from 'vue'
import Print from 'vue-print-nb'
Vue.use(Print)
export default {
props: {
height: {
type: String,
default: '500px'
}
},
mounted() {
this.init()
},
methods: {
init() {
const options = {
container: 'luckysheet', // 设定DOM容器的id
title: 'Luckysheet Demo', // 设定表格名称
lang: 'zh', // 设定表格语言
plugins: ['chart'], // 图表插件使用 https://blog.csdn.net/u013355529/article/details/116133127
showtoolbar: false, // 想要使用 showtoolbarConfig, 必须将showtoolbar设为false
showtoolbarConfig: {
undoRedo: true, //撤销重做,注意撤消重做是两个按钮,由这一个配置决定显示还是隐藏
mergeCell: true, // '合并单元格'
fillColor: true, // '单元格颜色'
textColor: true, // '文本颜色'
sortAndFilter: true, // '排序和筛选'
findAndReplace: true, // '查找替换'
chart: true, // 图表 (引入插件: https://blog.csdn.net/u013355529/article/details/116133127)
print: true // '打印'
}
}
luckysheet.create(options) // eslint-disable-line
},
async printExcel() { // 打印预览事件实现, 参考文档: https://blog.csdn.net/alan_ji198573/article/details/128624832
this.printSheet()
},
printSheet() { // 打印操作:自动选中打印区域,并生成打印截图,进行打印
document.querySelector('#print_html').style = "display:block"
window.luckysheet.hideGridLines()
let currentSelected = luckysheet.getRange() // 获取当前选中区域
if (currentSelected[0] != null &&
(currentSelected[0].row[1] - currentSelected[0].row[0] >= 1 ||
currentSelected[0].column[1] - currentSelected[0].column[0] >= 1)) { // 如果当前选中区只是一个单元格,则认为选取无效。
luckysheet.getScreenshotNew((imgSrc) => { // 将打印区域生成base64图片(*将生成的base64编码复制粘贴到浏览器地址框,是可以预览图片样式的),生成后执行的后续打印操作,取用匿名委托函数做为参数传入
window.luckysheet.showGridLines()
let $img = `<img src=${imgSrc} style="max-width: 90%;" />`
this.$nextTick(() => {
document.querySelector('#print_html').innerHTML = $img
})
document.getElementById('printExcelBtn').click()
setTimeout(() => {
document.querySelector('#print_html').style = "display:none"
}, 100)
})
}
else {
const RowColumn = this.getPrintSheetArea() // 获取打印区域的行列
// 因需要打印左边的边框,需重新设置第一列
// RowColumn.column[0] = 0;
luckysheet.setRangeShow(RowColumn) // 进行选区操作
luckysheet.getScreenshotNew((imgSrc) => { // 将打印区域生成base64图片(*将生成的base64编码复制粘贴到浏览器地址框,是可以预览图片样式的),生成后执行的后续打印操作,取用匿名委托函数做为参数传入
window.luckysheet.showGridLines()
const $img = `<img src=${imgSrc} style="max-width: 90%;" />`
this.$nextTick(() => {
document.querySelector('#print_html').innerHTML = $img
})
document.getElementById('printExcelBtn').click()
setTimeout(() => {
document.querySelector('#print_html').style = "display:none"
}, 100)
})
}
},
getPrintSheetArea() { // 获取打印区域(即表格中有内容、非空白的区域)(用row,column数组表示)
const sheetData = luckysheet.getSheetData();
let objRowColumn = {
row: [0, 0], // 行
column: [0, 0], // 列
};
sheetData.forEach((item, index) => { // * item是行、index是行索引、it是一行里的一格、itemIndex是这一格在这一行里的列索引
item.forEach((it, itemIndex) => { // 行数
if (it !== null) {
if (objRowColumn.row[1] < index) {
objRowColumn.row[1] = index; // row第二位
}
if (objRowColumn.column[1] < itemIndex) {
objRowColumn.column[1] = itemIndex; // column第二位
}
}
});
});
return objRowColumn;
},
}
}
</script>
<style scoped>
.luckyexcelConstentCss {
margin: 0 30px;
}
.luckyexcelCss {
width: 100%;
height: 100%;
}
</style>
⑤ 选择区域点击打印
文章来源:https://www.toymoban.com/news/detail-820003.html
打印成功会弹出打印弹窗
文章来源地址https://www.toymoban.com/news/detail-820003.html
到了这里,关于vue使用luckysheet,引入图表chartmix,实现打印按钮功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!