东丰在线网站建设,用于网站建设的费用怎么备注,品牌网站建设毛尖2,网站开发属于软件开发服务吗文章目录 前言一、Luckysheetvue3vite 例子如有启发#xff0c;可点赞收藏哟~ 前言
本文记录好用的开源在线表格 具体如图显示 另外记录下更名后的univer~#xff0c;如下图#xff08;有兴趣可自行详细了解#xff09; univer
在线思维导图 一、Luckysheet
参考git… 文章目录 前言一、Luckysheetvue3vite 例子如有启发可点赞收藏哟~ 前言
本文记录好用的开源在线表格 具体如图显示 另外记录下更名后的univer~如下图有兴趣可自行详细了解 univer
在线思维导图 一、Luckysheet
参考gitee 一款纯前端类似excel的在线表格功能强大、配置简单、完全开源。
vue3vite 例子
vue3vite
引入样式及脚本 link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/css/pluginsCss.css /link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/plugins.css /link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/luckysheet/dist/css/luckysheet.css /link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/luckysheet/dist/assets/iconfont/iconfont.css /script srchttps://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/js/plugin.js/scriptscript srchttps://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js/script安装所需依赖exceljs、file-saver和luckyexcel
npm i exceljs file-saver luckyexcel -S新建 components/excel.vue
templatediv styleposition: absolute; top: 0input iduploadBtn typefile changeloadExcel /spanOr Load remote xlsx file:/spanselect v-modelselected changeselectExceloption disabled valueChoose/optionoption v-foroption in options :keyoption.text :valueoption.value{{ option.text }}/option/selecta hrefjavascript:void(0) clickdownloadExcelDownload source xlsx file/a/divdiv idluckysheet/divdiv v-showisMaskShow idtipDownloading/div
/templatescript setup
import { ref, onMounted } from vue
import { exportExcel } from ./export
import LuckyExcel from luckyexcelconst isMaskShow ref(false)
const selected ref()
const jsonData ref({})
const options ref([{ text: Money Manager.xlsx, value: https://minio.cnbabylon.com/public/luckysheet/money-manager-2.xlsx },{text: Activity costs tracker.xlsx,value: https://minio.cnbabylon.com/public/luckysheet/Activity%20costs%20tracker.xlsx},{text: House cleaning checklist.xlsx,value: https://minio.cnbabylon.com/public/luckysheet/House%20cleaning%20checklist.xlsx},{text: Student assignment planner.xlsx,value: https://minio.cnbabylon.com/public/luckysheet/Student%20assignment%20planner.xlsx},{text: Credit card tracker.xlsx,value: https://minio.cnbabylon.com/public/luckysheet/Credit%20card%20tracker.xlsx},{ text: Blue timesheet.xlsx, value: https://minio.cnbabylon.com/public/luckysheet/Blue%20timesheet.xlsx },{text: Student calendar (Mon).xlsx,value: https://minio.cnbabylon.com/public/luckysheet/Student%20calendar%20%28Mon%29.xlsx},{text: Blue mileage and expense report.xlsx,value: https://minio.cnbabylon.com/public/luckysheet/Blue%20mileage%20and%20expense%20report.xlsx}
])const loadExcel (evt) {const files evt.target.filesif (files null || files.length 0) {alert(No files wait for import)return}let name files[0].namelet suffixArr name.split(.),suffix suffixArr[suffixArr.length - 1]if (suffix ! xlsx) {alert(Currently only supports the import of xlsx files)return}LuckyExcel.transformExcelToLucky(files[0], function (exportJson, luckysheetfile) {if (exportJson.sheets null || exportJson.sheets.length 0) {alert(Failed to read the content of the excel file, currently does not support xls files!)return}console.log(exportJson, exportJson)jsonData.value exportJsonwindow.luckysheet.destroy()window.luckysheet.create({container: luckysheet, //luckysheet is the container idshowinfobar: false,data: exportJson.sheets,title: exportJson.info.name,userInfo: exportJson.info.name.creator})})
}
const selectExcel (evt) {const value selected.valueconst name evt.target.options[evt.target.selectedIndex].innerTextif (value ) {return}isMaskShow.value trueLuckyExcel.transformExcelToLuckyByUrl(value, name, (exportJson, luckysheetfile) {if (exportJson.sheets null || exportJson.sheets.length 0) {alert(Failed to read the content of the excel file, currently does not support xls files!)return}console.log(exportJson, exportJson)jsonData.value exportJsonisMaskShow.value falsewindow.luckysheet.destroy()window.luckysheet.create({container: luckysheet, //luckysheet is the container idshowinfobar: false,data: exportJson.sheets,title: exportJson.info.name,userInfo: exportJson.info.name.creator})})
}
const downloadExcel () {// const value selected.value;;//// if(value.length0){// alert(Please select a demo file);// return;// }//// var elemIF document.getElementById(Lucky-download-frame);// if(elemIFnull){// elemIF document.createElement(iframe);// elemIF.style.display none;// elemIF.id Lucky-download-frame;// document.body.appendChild(elemIF);// }// elemIF.src value;exportExcel(luckysheet.getAllSheets(), 下载)
}// !!! create luckysheet after mounted
onMounted(() {luckysheet.create({container: luckysheet})
})
/scriptstyle scoped
#luckysheet {margin: 0px;padding: 0px;position: absolute;width: 100%;left: 0px;top: 30px;bottom: 0px;
}#uploadBtn {font-size: 16px;
}#tip {position: absolute;z-index: 1000000;left: 0px;top: 0px;bottom: 0px;right: 0px;background: rgba(255, 255, 255, 0.8);text-align: center;font-size: 40px;align-items: center;justify-content: center;display: flex;
}
/style
新建 exports.js
// import { createCellPos } from ./translateNumToLetter
import Excel from exceljsimport FileSaver from file-saverconst exportExcel function(luckysheet, value) {// 参数为luckysheet.getluckysheetfile()获取的对象// 1.创建工作簿可以为工作簿添加属性const workbook new Excel.Workbook()// 2.创建表格第二个参数可以配置创建什么样的工作表if (Object.prototype.toString.call(luckysheet) [object Object]) {luckysheet [luckysheet]}luckysheet.forEach(function(table) {if (table.data.length 0) return true// ws.getCell(B2).fill fills.const worksheet workbook.addWorksheet(table.name)const merge (table.config table.config.merge) || {}const borderInfo (table.config table.config.borderInfo) || {}// 3.设置单元格合并,设置单元格边框,设置单元格样式,设置值setStyleAndValue(table.data, worksheet)setMerge(merge, worksheet)setBorder(borderInfo, worksheet)return true})// return// 4.写入 bufferconst buffer workbook.xlsx.writeBuffer().then(data {// console.log(data, data)const blob new Blob([data], {type: application/vnd.ms-excel;charsetutf-8})console.log(导出成功)FileSaver.saveAs(blob, ${value}.xlsx)})return buffer
}var setMerge function(luckyMerge {}, worksheet) {const mergearr Object.values(luckyMerge)mergearr.forEach(function(elem) {// elem格式{r: 0, c: 0, rs: 1, cs: 2}// 按开始行开始列结束行结束列合并相当于 K10:M12worksheet.mergeCells(elem.r 1,elem.c 1,elem.r elem.rs,elem.c elem.cs)})
}var setBorder function(luckyBorderInfo, worksheet) {if (!Array.isArray(luckyBorderInfo)) return// console.log(luckyBorderInfo, luckyBorderInfo)luckyBorderInfo.forEach(function(elem) {// 现在只兼容到borderType 为range的情况// console.log(ele, elem)if (elem.rangeType range) {let border borderConvert(elem.borderType, elem.style, elem.color)let rang elem.range[0]// console.log(range, rang)let row rang.rowlet column rang.columnfor (let i row[0] 1; i row[1] 2; i) {for (let y column[0] 1; y column[1] 2; y) {worksheet.getCell(i, y).border border}}}if (elem.rangeType cell) {// col_index: 2// row_index: 1// b: {// color: #d0d4e3// style: 1// }const { col_index, row_index } elem.valueconst borderData Object.assign({}, elem.value)delete borderData.col_indexdelete borderData.row_indexlet border addborderToCell(borderData, row_index, col_index)// console.log(bordre, border, borderData)worksheet.getCell(row_index 1, col_index 1).border border}// console.log(rang.column_focus 1, rang.row_focus 1)// worksheet.getCell(rang.row_focus 1, rang.column_focus 1).border border})
}
var setStyleAndValue function(cellArr, worksheet) {if (!Array.isArray(cellArr)) returncellArr.forEach(function(row, rowid) {row.every(function(cell, columnid) {if (!cell) return truelet fill fillConvert(cell.bg)let font fontConvert(cell.ff,cell.fc,cell.bl,cell.it,cell.fs,cell.cl,cell.ul)let alignment alignmentConvert(cell.vt, cell.ht, cell.tb, cell.tr)let value if (cell.f) {value { formula: cell.f, result: cell.v }} else if (!cell.v cell.ct cell.ct.s) {// xls转为xlsx之后内部存在不同的格式都会进到富文本里即值不存在与cell.v而是存在于cell.ct.s之后// value cell.ct.s[0].vcell.ct.s.forEach(arr {value arr.v})} else {value cell.v}// style 填入到_value中可以实现填充色let letter createCellPos(columnid)let target worksheet.getCell(letter (rowid 1))// console.log(1233, letter (rowid 1))for (const key in fill) {target.fill fillbreak}target.font fonttarget.alignment alignmenttarget.value valuereturn true})})
}var fillConvert function(bg) {if (!bg) {return {}}// const bgc bg.replace(#, )let fill {type: pattern,pattern: solid,fgColor: { argb: bg.replace(#, ) }}return fill
}var fontConvert function(ff 0,fc #000000,bl 0,it 0,fs 10,cl 0,ul 0
) {// luckysheetff(样式), fc(颜色), bl(粗体), it(斜体), fs(大小), cl(删除线), ul(下划线)const luckyToExcel {0: 微软雅黑,1: 宋体Song,2: 黑体ST Heiti,3: 楷体ST Kaiti,4: 仿宋ST FangSong,5: 新宋体ST Song,6: 华文新魏,7: 华文行楷,8: 华文隶书,9: Arial,10: Times New Roman ,11: Tahoma ,12: Verdana,num2bl: function(num) {return num 0 ? false : true}}// 出现Bug导入的时候ff为luckyToExcel的vallet font {name: typeof ff number ? luckyToExcel[ff] : ff,family: 1,size: fs,color: { argb: fc.replace(#, ) },bold: luckyToExcel.num2bl(bl),italic: luckyToExcel.num2bl(it),underline: luckyToExcel.num2bl(ul),strike: luckyToExcel.num2bl(cl)}return font
}var alignmentConvert function(vt default,ht default,tb default,tr default
) {// luckysheet:vt(垂直), ht(水平), tb(换行), tr(旋转)const luckyToExcel {vertical: {0: middle,1: top,2: bottom,default: top},horizontal: {0: center,1: left,2: right,default: left},wrapText: {0: false,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] templateborder[right] templateborder[bottom] templateborder[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 1let s while (n 0) {s String.fromCharCode((n % len) ordA) sn Math.floor(n / len) - 1}return s
}export {exportExcel
}运行后预览显示可导入下载 如有启发可点赞收藏哟~