创新项目实训
任务
项目的功能已经基本实现,为了扩展系统数据分析的功能,我们准备参考ChartExcel在Excel上实现一个简单的在线AI操作功能。
在线Excel
本项目使用开源工具LuckySheet。
Luckysheet是一款纯前端的类Excel在线表单,功能强大、配置简单、完全开源。可以通过CDN或npm部署。使用CDN方法。即在你的vue项目中的public/index.html中添加以下脚本代码。头
链接rel=\’stylesheet\’ href=\’https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/css/pluginsCss.css\’ /
链接rel=\’stylesheet\’ href=\’https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/plugins.css\’/
链接rel=\’stylesheet\’ href=\’https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/css/luckysheet.css\’ /
链接rel=\’stylesheet\’ href=\’https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/assets/iconfont/iconfont.css\’ /
/头
身体
脚本src=\’https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/js/plugin.js\’/script
脚本src=\’https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/luckysheet.umd.js\’/script
!–您的应用程序–
/身体
手动的
创建一个容器! — key 是id —
分配
v-loading=\’正在加载\’
element-loading-text=\’疯狂加载\’
element-loading-spinner=\’el-icon-loading\’
元素加载背景=\’rgba(0,0,0,0.8)\’
id=\’幸运表\’
样式=\’margin-top:39px;padding:0px;position:absolute;width:1470px;height:623px;left: 0px;top: 0px;\’
/div
挂载页面时,初始化并创建实例mount() {
幸运表.create({
容器:“幸运单”,
显示信息栏: 假,
showsheetbar: 真实,
showtoolbar: 真实,
显示统计栏: 真实,
显示状态栏: 真实,
showgrid: 真实,
showrowheader: 真实,
显示columnheader: 真实,
行高: 25,
列宽: 100,
变焦: 100,
默认缩放: 100,
默认行高: 25,
默认列宽: 100,
lang: \’zh\’,
//更多配置选项.
});
},
至此,基本功能就可以实现了。有关更多功能或详细信息,请参阅完整配置。
导入Excel功能
我们将使用一个名为LuckyExcel 的工具。
Luckyexcel是一个由Luckysheet改编而来的Excel导入导出库。仅支持.xlsx 格式文件(不支持.xls)。但是,似乎没有任何官方导出功能。通过npm或CDN部署,使用npm install luckyexcel。它相对容易使用。
从“luckyexcel”导入介绍LuckyExcel。
一起使用el-upload 和el-upload
动作=\’#\’
第:章自动上传=\’假\’
第:章显示文件列表=\’假\’
:on-change=\’导入Excel\’
el-button icon=\’el-icon-upload2\’导入Excel/el-button
/el-上传
导入Excel(文件,文件列表){
这个.file=文件.raw
//使用LuckyExcel 转换文件
LuckyExcel.transformExcelToLucky(
这个文件,
(导出Json)={
console.log(exportJson.sheets)
this.totalRow=exportJson.sheets[0].celldata[exportJson.sheets[0].celldata.length-1].r
this.totalCol=exportJson.sheets[0].celldata[exportJson.sheets[0].celldata.length-1].c
//console.log(this.totalCol)
幸运表.create({
容器:“幸运单”,
显示信息栏: 假,
showsheetbar: 真实,
showtoolbar: 真实,
显示统计栏: 真实,
显示状态栏: 真实,
showgrid: 真实,
showrowheader: 真实,
显示columnheader: 真实,
行高: 25,
列宽: 100,
变焦: 100,
默认缩放: 100,
默认行高: 25,
默认列宽: 100,
lang: \’zh\’,
data:exportJson.sheets
});
},
(错误)={
console.error(\’导入失败。文件是有效的xlsx 吗?\’, error);
}
);
},
导出Excel
官方有两种方法,但是这次我们将使用file-saver和exceljs相结合的方法。
安装文件保护程序和Exceljs——npm。 i 文件保护程序下载Exceljs 文件。 export.js//从\’./translateNumToLetter\’ 导入{ createCellPos }
const Excel=require(\’exceljs\’)
从“文件保护程序”导入文件保护程序
导出var testaaa=函数(){
console.log(\’.\’);
}
导出var exportExcel=函数(luckysheet, 值) {
//参数是用luckysheet.getluckysheetfile()获得的对象
//1.创建工作簿并为工作簿添加属性
const 工作簿=new Excel.Workbook()
//2. 创建表。第二个参数允许您设置将创建的工作表的类型。
if (Object.prototype.toString.call(luckysheet)===\'[Object Object]\’) {
幸运单=【幸运单】
}
luckysheet.forEach(函数(表) {
if (table.data.length===0) 返回true
//ws.getCell(\’B2\’).fill=填充。
const 工作表=workbook.addWorksheet(table.name)
const merge=(table.config table.config.merge) || {}
const borderInfo=(table.config table.config.borderInfo) ||
//3.设置单元格合并、设置单元格边框、设置单元格样式、设置值
setStyleAndValue(表.数据,工作表)
setMerge(合并,工作表)
setBorder(边框信息,工作表)
返回真
})
//返回
//4. 写入缓冲区
constbuffer=workbook.xlsx.writeBuffer().then(data={
//console.log(\’数据\’, 数据)
const blob=new Blob([数据], {
type: \’应用程序/vnd.ms-excel;charset=utf-8\’
})
console.log(\’导出成功!\’)
FileSaver.saveAs(blob, `${value}.xlsx`)
})
返回缓冲区
}
var setMerge=函数(luckyMerge={}, 工作表) {
const mergearr=Object.values(luckyMerge)
mergearr.forEach(函数(elem) {
//元素格式:{r: 0, c: 0, rs: 1, cs: 2}
//按起始行、起始列、结束行、结束列合并(相当于K10:M12)
工作表.mergeCells(
elem.r + 1,
elem.c+1,
elem.r + elem.rs,
elem.c + elem.cs
)
})
}
var setBorder=函数(luckyBorderInfo,工作表){
if (!Array.isArray(luckyBorderInfo)) 返回
//console.log(\’luckyBorderInfo\’, luckyBorderInfo)
luckyBorderInfo.forEach(函数(elem) {
//目前只兼容borderType范围
//console.log(\’ele\’, elem)
if (elem.rangeType===\’范围\’) {
让边框=borderConvert(elem.borderType, elem.style, elem.color)
让范围=elem.range[0]
//console.log(\’范围\’, 范围)
让行=rang.row
让列=rang.column
for (让i=行[0] + 1; i 行[1] + 2; i++) {
for (让y=列[0] + 1; y 列[1] + 2; y++) {
worksheet.getCell(i, y).border=边框
}
}
}
if (elem.rangeType===\’单元格\’) {
//col_index: 2
//row_index: 1
//b: {
//color: \’#d0d4e3\’
//样式: 1
//}
const {col_index, row_index}=elem.value
const borderData=Object.assign({}, elem.value)
删除borderData.col_index
删除borderData.row_index
让边框=addborderToCell(borderData, row_index,col_index)
//console.log(\’bordre\’, border, borderData)
worksheet.getCell(row_index + 1,col_index + 1).border=边框
}
//console.log(rang.column_focus + 1, rang.row_focus + 1)
//worksheet.getCell(rang.row_focus + 1, rang.column_focus + 1).border=边框
})
}
var setStyleAndValue=函数(cellArr, 工作表) {
if (!Array.isArray(cellArr)) 返回
cellArr.forEach(函数(行,rowid) {
row.every(函数(单元格, 列ID) {
if (!cell) 返回true
让填充=fillConvert(cell.bg)
让字体=字体转换(
细胞.ff,
细胞.fc,
细胞.bl,
细胞它,
细胞.fs,
细胞.cl,
细胞.ul
)
letalignment=alignmentConvert(cell.vt, cell.ht, cell.tb, cell.tr)
设定值=\’\’
if (cell.f) {
值={ 公式: cell.f, 结果: cell.v }
} else if (!cell.v cell.ct cell.ct.s) {
//xls转换为xlsx时,内部格式不同,都是富文本。也就是说,该值不存在于cell.v 中,而是出现在cell.ct.s 之后。
//值=cell.ct.s[0].v
cell.ct.s.forEach(arr={
值+=数组v
})
} 除此之外{
值=单元格.v
}
//填充样式为_value以实现填充颜色
让字符=createCellPos(columnid)
让目标=worksheet.getCell(字母+ (rowid + 1))
//console.log(\’1233\’, 字符+ (行ID + 1))
for (嵌入const 键) {
目标.填充=填充
休息
}
目标.font=字体
目标.对齐=对齐
目标值=价值
返回真
})
})
}
var fillConvert=函数(bg) {
如果(!bg){
返回{}
}
//const bgc=bg.replace(\’#\’, \’\’)
填充={
type:“模式”,
图案:\’实心\’,
fgColor: { argb: bg.replace(\’#\’, \’\’) }
}
返回填充
}
var 字体转换=函数(
ff=0,
fc=\’#000000\’,
bb=0,
它=0,
FS=10,
cl=0,
ul=0
){
//幸运表:ff(样式)、fc(颜色)、bl(粗体)、it(斜体)、fs(大小)、cl(删除线)、ul(下划线)
常量luckyToExcel={
0: \’微软雅黑\’,
1:“歌曲”,
2:\’ST海地\’,
3:\’ST凯蒂\’,
4:\’ST粉丝歌\’,
5:“ST歌”,
6:《中国新魏》,
7: \’汉字\’,
8: \’中国的官方字符\’,
9: \’空中\’,
10: \’时代新罗马\’,
11: \’塔霍马\’,
12: \’维达纳\’,
num2bl: 函数(数字){
返回值===0 : true ?
}
}
//出现Bug,导入时ff为luckyToExcel的值
让字体={
name: typeof ff===\’数字\’ ? luckyToExcel[ff] : ff,
家庭: 1、
尺寸: fs,
color: { argb: fc.replace(\’#\’, \’\’) },
Bold: luckyToExcel.num2bl(bl),
斜体: luckyToExcel.num2bl(it),
下划线: luckyToExcel.num2bl(ul),
Strike: luckyToExcel.num2bl(cl)
}
返回字体
}
varalignmentConvert=函数(
vt=\’默认\’,
ht=\’默认\’,
tb=\’默认\’,
tr=\’默认\’
){
//luckysheet:vt(垂直)、ht(水平)、tb(换行)、tr(旋转)
常量luckyToExcel={
垂直: {
0: \’中级\’,
1:“顶”,
2: \”底部\”,
默认:“顶部”
},
水平: {
0: \’中心\’,
1: \’左\’,
2: “是”,
默认: \’左\’
},
文本换行: {
0: 错误,
1: false,
2: true,
default: false
},
textRotation: {
0: 0,
1: 45,
2: -45,
3: \’vertical\’,
4: 90,
5: -90,
default: 0
}
}
let alignment = {
vertical: luckyToExcel.vertical[vt],
horizontal: luckyToExcel.horizontal[ht],
wrapText: luckyToExcel.wrapText[tb],
textRotation: luckyToExcel.textRotation[tr]
}
return alignment
}
var borderConvert = function(borderType, style = 1, color = \’#000\’) {
// 对应luckysheet的config中borderinfo的的参数
if (!borderType) {
return {}
}
const luckyToExcel = {
type: {
\’border-all\’: \’all\’,
\’border-top\’: \’top\’,
\’border-right\’: \’right\’,
\’border-bottom\’: \’bottom\’,
\’border-left\’: \’left\’
},
style: {
0: \’none\’,
1: \’thin\’,
2: \’hair\’,
3: \’dotted\’,
4: \’dashDot\’, // \’Dashed\’,
5: \’dashDot\’,
6: \’dashDotDot\’,
7: \’double\’,
8: \’medium\’,
9: \’mediumDashed\’,
10: \’mediumDashDot\’,
11: \’mediumDashDotDot\’,
12: \’slantDashDot\’,
13: \’thick\’
}
}
let template = {
style: luckyToExcel.style[style],
color: { argb: color.replace(\’#\’, \’\’) }
}
let border = {}
if (luckyToExcel.type[borderType] === \’all\’) {
border[\’top\’] = template
border[\’right\’] = template
border[\’bottom\’] = template
border[\’left\’] = template
} else {
border[luckyToExcel.type[borderType]] = template
}
// console.log(\’border\’, border)
return border
}
function addborderToCell(borders, row_index, col_index) {
let border = {}
const luckyExcel = {
type: {
l: \’left\’,
r: \’right\’,
b: \’bottom\’,
t: \’top\’
},
style: {
0: \’none\’,
1: \’thin\’,
2: \’hair\’,
3: \’dotted\’,
4: \’dashDot\’, // \’Dashed\’,
5: \’dashDot\’,
6: \’dashDotDot\’,
7: \’double\’,
8: \’medium\’,
9: \’mediumDashed\’,
10: \’mediumDashDot\’,
11: \’mediumDashDotDot\’,
12: \’slantDashDot\’,
13: \’thick\’
}
}
// console.log(\’borders\’, borders)
for (const bor in borders) {
// console.log(bor)
if (borders[bor].color.indexOf(\’rgb\’) === -1) {
border[luckyExcel.type[bor]] = {
style: luckyExcel.style[borders[bor].style],
color: { argb: borders[bor].color.replace(\’#\’, \’\’) }
}
} else {
border[luckyExcel.type[bor]] = {
style: luckyExcel.style[borders[bor].style],
color: { argb: borders[bor].color }
}
}
}
return border
}
function createCellPos(n) {
let ordA = \’A\’.charCodeAt(0)
let ordZ = \’Z\’.charCodeAt(0)
let len = ordZ – ordA + 1
let s = \’\’
while (n >= 0) {
s = String.fromCharCode((n % len) + ordA) + s
n = Math.floor(n / len) – 1
}
return s
}
直接调用方法即可 downloadExcel(){
exportExcel(luckysheet.getAllSheets(),\”下载\”)
},
贴个图
扩展对话框
对话框 <div class=\”input-container\”>
<el-input v-model=\”need\” type=\”textarea\” style=\”width:400px;\” :rows=\”4\” placeholder=\”输入内容\” />
<div class=\”button-container\”>
<el-button circle icon=\”el-icon-video-play\” @click=\”handleExcel\”></el-button>
<el-button circle icon=\”el-icon-refresh-left\” @click=\”handleBack\”></el-button>
</div>
</div>
<style scoped>
.input-container {
position: absolute;
bottom: 80px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(90, 79, 79, 0.5);
padding: 10px;
border-radius: 5px;
z-index: 1000;
display: flex; /* 使用Flexbox布局 */
}
.button-container {
display: flex;
flex-direction: column; /* 使按钮垂直堆叠 */
margin-left: 10px;
margin-top: 10px;
align-items: flex-end;; /* 设置交叉轴对齐方式 */
}
</style>
贴张图,看着有模有样了…
LuckySheet中的API学习
更多API的操作请查看官网,下面简单介绍几种常用的。选区操作即自动获取全部数据。//获取第一个sheet中的有数据的第一行,第一列,最后一行和最后一列
this.totalCol=luckysheet.getAllSheets()[0].celldata[luckysheet.getAllSheets()[0].celldata.length-1].c
this.firstCol=luckysheet.getAllSheets()[0].celldata[0].c
this.totalRow=luckysheet.getAllSheets()[0].celldata[luckysheet.getAllSheets()[0].celldata.length-1].r
this.firstRow=luckysheet.getAllSheets()[0].celldata[0].r
//选区操作,获得所有有数据的区域,即页面显示会出现高亮
luckysheet.setRangeShow({row:[this.firstRow,this.totalRow],column:[this.firstCol,this.totalCol]})
//将选区部分的数据,导出为JSON格式,false的意思是首行不是表头
luckysheet.getRangeJson(false)
表格操作//在raw行column列设置值为value
luckysheet.setCellValue(raw,column,value)
回退操作handleBack(){
luckysheet.undo()
},
AI操作表格
有了上面的API,我们的设计思路就是,将表格中的数据导出为JSON格式与输入框输入的需求一并传给AI,让其生成新的JSON格式的数据,例如多生成一行。
由于我们的模型是文本模型,对于计算等不能支持,故采用让其生成函数表达式,即如求平均值就生成文本“=(10+10)/2”,或者“=SUM(B9:C9)”表达式即可。
最后将生成的JSON数组,传回到前端后,使用setCellValue方法即可。
showJsonData.forEach(item=>{
var column=0
Object.keys(item).forEach(key=>{
luckysheet.setCellValue(raw,column,item[key])
column++
})
raw++
})
展示
JSON格式数据[
{\”A\”: \”省份\”, \”B\”: \”GDP\”},
{\”A\”: \”山东\”, \”B\”: 10},
{\”A\”: \”河南\”, \”B\”: 20},
{\”A\”: \”陕西\”, \”B\”: 50},
{\”A\”: \”山西\”, \”B\”: 15},
{\”A\”: \”福建\”, \”B\”: 100},
{\”A\”: \”河北\”, \”B\”: 60},
{\”A\”: \”宁夏\”, \”B\”: 200},
{\”A\”: \”甘肃\”, \”B\”: 10},
{\”A\”: \”平均值\”, \”B\”:\”=(10+20+50+15+100+60+200+10)/8\”}
]
前端展示,效果还行…问题是可能AI还不够聪明,对于一些复杂的功能不能够实现,还有待学习改进哇~
#以上关于LuckySheet结合通义千问仿ChatExcel的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91974.html