提示:文章寫完后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔
前言
提示:這里可以添加本文要記錄的大概內(nèi)容:
這兩年,在線表格協(xié)作工具越來越火,但開源界一直沒有相關(guān)的實(shí)現(xiàn),被壟斷在幾個(gè)大廠手上,隨著Luckysheet 的橫空出世,開源界終于也有一個(gè)漂亮能打的在線表格,而且仔細(xì)研究后發(fā)現(xiàn)Luckysheet與excel已經(jīng)特別接近,也實(shí)現(xiàn)了協(xié)同編輯,故基于Luckysheet,本項(xiàng)目實(shí)現(xiàn)了一個(gè)協(xié)同編輯的demo,以上是前作者說的,于是我就開始給他填坑
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、lucksheet是什么?
在線excel編輯
友情鏈接:
.Luckysheet
??Luckysheet is an online spreadsheet like excel that is powerful, simple to configure, and completely open source
二、 ecsheet 基于MongoDB存儲(chǔ)
1.為啥選擇這個(gè)開源,這個(gè)項(xiàng)目選擇原因單單是因?yàn)橄啾扔趧e的項(xiàng)目多一個(gè)首頁也就是展示excel的目錄。
2.不足:沒有導(dǎo)入導(dǎo)出的協(xié)同
三、話不多說上開源Cy_lucksheetProfect
1.原先demo 沒有導(dǎo)入導(dǎo)出,開源案例中都是前端導(dǎo)入前端導(dǎo)出,沒辦法配合協(xié)同存到數(shù)據(jù)庫,于是自己分析代碼寫出來了
2.解釋為啥前端導(dǎo)入導(dǎo)出沒辦法協(xié)同:
這是:協(xié)同lucksheet初始化代碼:
container: "${wb.option.container}", // 設(shè)定DOM容器的id
title: "${wb.option.title}", // 設(shè)定表格名稱
lang: "${wb.option.lang}",
allowUpdate: true,
loadUrl: window.location.protocol + localurl + "/load/${wb.id}",
loadSheetUrl: window.location.protocol + localurl + "/loadSheet/${wb.id}",
updateUrl: "ws://"+localurl + "/ws/" + Math.round(Math.random() * 100) + "/${wb.id}",
functionButton : '<button id="" class="btn btn-primary btn-danger" style=" padding:3px 6px; font-size: 12px; margin-right: 5px;" onclick="exportHandle()">導(dǎo)出</button><button id="" class="btn btn-primary btn-danger" style=" padding:3px 6px; font-size: 12px; margin-right: 85px;" onclick="exportHandles()">在線導(dǎo)出</button>',
這是:普通:
container: 'luckysheet', //luckysheet is the container id
showinfobar:false,
lang: 'zh', // 設(shè)定表格語言
allowEdit: true,//作用:是否允許前臺(tái)編輯
// allowUpdate: true,
allowCopy: true, //是否允許拷貝
showtoolbar: true, //是否第二列顯示工具欄
showinfobar: true, //是否顯示頂部名稱欄
showsheetbar: true, //是否顯示底部表格名稱區(qū)域
showstatisticBar: true, //是否顯示底部計(jì)數(shù)欄
pointEdit: false, //是否是編輯器插入表格模式
pointEditUpdate: null, //編輯器表格更新函數(shù)
data:exportJson.sheets,
title:exportJson.info.name,
userInfo:exportJson.info.name.creator,
functionButton : '<button id="" class="btn btn-primary btn-danger" style=" padding:3px 6px; font-size: 12px; margin-right: 5px;" onclick="exportHandle()">導(dǎo)出</button><button id="" class="btn btn-primary btn-danger" style=" padding:3px 6px; font-size: 12px; margin-right: 85px;" onclick="exportHandles()">在線導(dǎo)出</button>',
});
在我的使用中:data 屬性和loadUrl 不能并存 loadUrl就是從數(shù)據(jù)庫獲得data 這就是協(xié)同的區(qū)別
四、解決辦法
1.前端導(dǎo)入
var input = document.querySelector('input');
input.addEventListener('change', importExcelsss);
/**
* 獲取excel數(shù)據(jù)加載到頁面上
* @param event
*/
function importExcelsss(event) {
alert("導(dǎo)入過程中請(qǐng)勿關(guān)閉窗口,請(qǐng)稍后...\n如果遇到大文件導(dǎo)出未響應(yīng)請(qǐng)點(diǎn)擊等待");
var file = event.target.files[0];
var fileName = file.name;
fileName = fileName + "";
//將文件加載到頁面上
LuckyExcel.transformExcelToLucky(file, 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, luckysheetfile);
window.luckysheet.destroy();
window.luckysheet.create({
container: 'luckysheet', //luckysheet is the container id
showinfobar:false,
lang: 'zh', // 設(shè)定表格語言
allowEdit: true,//作用:是否允許前臺(tái)編輯
// allowUpdate: true,
allowCopy: true, //是否允許拷貝
showtoolbar: true, //是否第二列顯示工具欄
showinfobar: true, //是否顯示頂部名稱欄
showsheetbar: true, //是否顯示底部表格名稱區(qū)域
showstatisticBar: true, //是否顯示底部計(jì)數(shù)欄
pointEdit: false, //是否是編輯器插入表格模式
pointEditUpdate: null, //編輯器表格更新函數(shù)
data:exportJson.sheets,
title:exportJson.info.name,
userInfo:exportJson.info.name.creator,
functionButton : '<button id="" class="btn btn-primary btn-danger" style=" padding:3px 6px; font-size: 12px; margin-right: 5px;" onclick="exportHandle()">導(dǎo)出</button><button id="" class="btn btn-primary btn-danger" style=" padding:3px 6px; font-size: 12px; margin-right: 85px;" onclick="exportHandles()">在線導(dǎo)出</button>',
});
});
}
可以看到借助 lucksheet 官網(wǎng)的 luckyexcel.umd.js 實(shí)現(xiàn)前端導(dǎo)出(bug:切記 lucksheet 里面使用了jquery 和jsscript,再次引用這兩個(gè)會(huì)導(dǎo)致lucksheet 編輯導(dǎo)出異常 )
很顯然,前端的導(dǎo)出沒辦法將放在協(xié)同上做(已解決往下看)
2.前端導(dǎo)出三種辦法(兩種已經(jīng)實(shí)現(xiàn),還有一種想象的到)
1.借助excel.js 實(shí)現(xiàn)這是個(gè)vue用的比較多的,但我們可以用htm調(diào)用:
function exportHandles(){
var jsdata = new Array();
var sheets = luckysheet.getAllSheets();
exportExcel(sheets);
}
var exportExcel = async function (luckysheet) { // 參數(shù)為luckysheet.getluckysheetfile()獲取的對(duì)象
// 1.創(chuàng)建工作簿,可以為工作簿添加屬性
const workbook = new ExcelJS.Workbook()
// 2.創(chuàng)建表格,第二個(gè)參數(shù)可以配置創(chuàng)建什么樣的工作表
luckysheet.every(function (table) {
console.log(JSON.stringify(table.data))
if (table.data.length === 0) return true
const worksheet = workbook.addWorksheet(table.name)
// 3.設(shè)置單元格合并,設(shè)置單元格邊框,設(shè)置單元格樣式,設(shè)置值
setStyleAndValue(table.data, worksheet)
setMerge(table.config.merge, worksheet)
setBorder(table.config.borderInfo, worksheet)
//setwidthcol(table.data, worksheet);
return true
})
// 4.寫入 buffer
const buf = await workbook.xlsx.writeBuffer();
// 下載 excel
workbook.xlsx.writeBuffer().then((buf) => {
let blob = new Blob([buf], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' });
const downloadElement = document.createElement('a')
let href = window.URL.createObjectURL(blob)
downloadElement.href = href
downloadElement.download = document.getElementById("luckysheet_info_detail_input").value+".xlsx"; // 文件名字
document.body.appendChild(downloadElement)
downloadElement.click()
document.body.removeChild(downloadElement) // 下載完成移除元素
window.URL.revokeObjectURL(href) // 釋放掉blob對(duì)象
});
}
var setMerge = function (luckyMerge = {}, worksheet) {
const mergearr = Object.values(luckyMerge)
mergearr.forEach(function (elem) { // elem格式:{r: 0, c: 0, rs: 1, cs: 2}
// 按開始行,開始列,結(jié)束行,結(jié)束列合并(相當(dāng)于 K10:M12)
worksheet.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
luckyBorderInfo.forEach(function (elem) {
var val=elem.value;
let border = {}
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'
}
}
if(val.t!=undefined){
border['top'] = {style:luckyToExcel.style[val.t.style] , color: val.t.color}
}
if(val.r!=undefined){
border['right'] = {style:luckyToExcel.style[val.r.style] , color: val.r.color}
}
if(val.b!=undefined){
border['bottom'] = {style:luckyToExcel.style[val.b.style] , color: val.b.color}
}
if(val.l!=undefined){
border['left'] = {style:luckyToExcel.style[val.l.style] , color: val.l.color}
}
worksheet.getCell(val.row_index + 1, val.col_index + 1).border = border
})
}
var setStyleAndValue = function (cellArr, worksheet) {
if (!Array.isArray(cellArr)) return
cellArr.forEach(function (row, rowid) {
const dbrow = worksheet.getRow(rowid+1);
dbrow.height=luckysheet.getRowHeight([rowid])[rowid]/1.5;
row.every(function (cell, columnid) {
if (!cell) return true
if(rowid==0){
const dobCol = worksheet.getColumn(columnid+1);
dobCol.width=luckysheet.getColumnWidth([columnid])[columnid]/8;
}
let 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
console.log(JSON.stringify(cell));
var v='';
if(cell.ct.t=='inlineStr'){
var s=cell.ct.s;
s.forEach(function(val,num){
v+=val.v;
})
}else{
v=cell.v;
}
if (cell.f) {
value = { formula: cell.f, result: v }
} else {
value = v
}
let target = worksheet.getCell(rowid + 1, columnid + 1)
target.fill = fill
target.font = font
target.alignment = alignment
target.value = value
return true
})
})
}
var fillConvert = function (bg) {
if (!bg) {
return {
type: 'pattern',
pattern: 'solid',
fgColor:{argb:'#ffffff'.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) { // luckysheet:ff(樣式), 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
}
}
let font = {
name: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(旋轉(zhuǎn))
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') { // 對(duì)應(yīng)luckysheet的config中borderinfo的的參數(shù)
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
}
return border
}
這樣前端導(dǎo)出就實(shí)現(xiàn)了,這個(gè)協(xié)同也可以用,缺點(diǎn)導(dǎo)出有缺失,性能很快,
2.借助javapoi 解析傳會(huì)前端
function importHandler(){
let upload = document.getElementById("Luckyexcel-demo-file");
// let selectADemo = document.getElementById("Luckyexcel-select-demo");
// let downlodDemo = document.getElementById("Luckyexcel-downlod-file");
// let mask = document.getElementById("lucky-mask-demo");
if(upload){
window.onload = () => {
upload.addEventListener("change", function(evt){
var files = evt.target.files;
if(files==null || files.length==0){
alert("No files wait for import");
return;
}
let name = files[0].name;
let 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, luckysheetfile)
console.log("exportJson");
//ajax 請(qǐng)求 接口 將數(shù)據(jù)傳遞給后臺(tái) 并返回一個(gè)id
$.ajax({
type: "POST",
url: "/excel/importFile",
data: {
"exceldata": JSON.stringify(exportJson),
},
dataType: "json",
success: function(data){
console.log(data);
if(data.code==200){
console.log(data);
window.location.href = "/index/"+data.data;
}else{
alert(data.msg);
}
},
error: function(data){
console.log(data.toString());
alert("Failed to import the excel file");
}
});
});
});
}
}
}
importHandler();
調(diào)用 /excel/importFile 接口
public class ExportExcelController {
@GetMapping("/export")
public String exportExcel() {
return "export";
}
@PostMapping("/excel/exportFile")
public void downExcelFile(@RequestParam(value = "exceldata") String exceldata, HttpServletRequest request,
HttpServletResponse response) {
// 去除luckysheet中 
的換行
exceldata = exceldata.replace("
", "\\r\\n");
ExcelUtils.exportLuckySheetXlsx(exceldata, request, response);
}
}
借助ExcelUtils.exportLuckySheetXlsx() 導(dǎo)出
3.模板導(dǎo)入模板導(dǎo)出
設(shè)想,應(yīng)該沒問題 ,大家可以看這個(gè)博客:
https://blog.csdn.net/u014632228/article/details/109738221
4.其實(shí)結(jié)合以上除了導(dǎo)入需要寫到數(shù)據(jù)庫寫沒啥 ,完全可以用導(dǎo)出來改:
還一個(gè)是導(dǎo)入,導(dǎo)出都需要優(yōu)化我個(gè)人覺得 lucksheet 這個(gè)json完全可以寫一個(gè)優(yōu)化版的全部上傳和下載(導(dǎo)出前端可以不考慮)
注:post 請(qǐng)求超過2MB 需要配置下 server: port: 9999 tomcat: # tomcat的URI編碼 uri-encoding: UTF-8 # tomcatpost max-http-form-post-size: -1
5、在線導(dǎo)入核心,將前端導(dǎo)入 數(shù)據(jù)傳給后端 解析 創(chuàng)建一個(gè)新的excel 將全部數(shù)據(jù)加載到loadURL 數(shù)據(jù)源(MongoB)
1.上代碼:
@PostMapping("/excel/importFile")
public AjaxResult importExcelFile(@RequestParam(value = "exceldata") String exceldata, HttpServletRequest request,
HttpServletResponse response) throws IOException {
// 去除luckysheet中 
的換行
exceldata = exceldata.replace("
", "\\r\\n");
//實(shí)例化一個(gè)Gson對(duì)象
cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(exceldata);
// cn.hutool.json.JSONArray jsonArray = JSONUtil.parseArray(exceldata);
cn.hutool.json.JSONObject info= JSONUtil.parseObj(jsonObject.get("info"));
cn.hutool.json.JSONArray sheetJsonarry= JSONUtil.parseArray(jsonObject.get("sheets"));
WorkBookEntity wb = new WorkBookEntity();
wb.setName(info.get("name").toString().replace(".xlsx", ""));
wb.setOption(SheetUtil.getDefautOption(info));
WorkBookEntity saveWb = workBookRepository.save(wb);
sheetJsonarry.forEach(sheet -> {
WorkSheetEntity ws = new WorkSheetEntity();
ws.setWbId(saveWb.getId());
cn.hutool.json.JSONObject jsonObjects = JSONUtil.parseObj(sheet);
ws.setData(jsonObjects);
ws.setDeleteStatus(0);
workSheetRepository.save(ws);
});
// System.out.println(jsonObject);
//
JSONObject jsonObj = JSONObject.fromObject(exceldata);
//轉(zhuǎn)為相應(yīng)的實(shí)體對(duì)象
// JsonRootBean jsonRootBean = gson.fromJson(exceldata, JsonRootBean.class);
//字符串去除 .xlsx
// 將json數(shù)據(jù)轉(zhuǎn)為jsonArray
//轉(zhuǎn)換為json格式
// WorkBookEntity wb = new WorkBookEntity();
// wb.setName(jsonRootBean.getInfo().getName().replace(".xlsx", ""));
// wb.setOption(SheetUtil.getDefautOption(jsonRootBean));
// WorkBookEntity saveWb = workBookRepository.save(wb);
// //生成sheet數(shù)據(jù)
// jsonRootBean.getSheets().forEach(sheet -> {
// WorkSheetEntity ws = new WorkSheetEntity();
// ws.setWbId(saveWb.getId());
// cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(sheet);
// ws.setData(jsonObject);
// ws.setDeleteStatus(0);
// workSheetRepository.save(ws);
// });
// return new AjaxResult(200, "success", saveWb.getId().toString());
return new AjaxResult(200, "success", saveWb.getId().toString());
}
// @PostMapping("/excel/importFile")
// public JSONObject importExcelFile(@RequestParam(value = "exceldata") String exceldata) {
// Gson gson = new Gson();
// JSONObject jsonObj = JSONObject.fromObject(exceldata);
轉(zhuǎn)為相應(yīng)的實(shí)體對(duì)象
//
// JsonRootBean jsonRootBean = gson.fromJson(jsonObj.toString(), JsonRootBean.class);
// //字符串去除 .xlsx
//
//
// // 將json數(shù)據(jù)轉(zhuǎn)為jsonArray
//
//
// //轉(zhuǎn)換為json格式
// WorkBookEntity wb = new WorkBookEntity();
// wb.setName(jsonRootBean.getInfo().getName().replace(".xlsx", ""));
// wb.setOption(SheetUtil.getDefautOption(jsonRootBean));
// WorkBookEntity saveWb = workBookRepository.save(wb);
// //生成sheet數(shù)據(jù)
// jsonRootBean.getSheets().forEach(sheet -> {
// WorkSheetEntity ws = new WorkSheetEntity();
// ws.setWbId(saveWb.getId());
// cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(sheet);
// ws.setData(jsonObject);
// ws.setDeleteStatus(0);
// workSheetRepository.save(ws);
// });
//
// //寫一個(gè)json字符串,返回給前端
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("id", saveWb.getId());
//
// return jsonObject;
//
//
//
//
//
注:這里不可以用json實(shí)體 實(shí)體不全報(bào)錯(cuò)還缺少數(shù)據(jù)
2.代碼解析
想象一下導(dǎo)入無非就是創(chuàng)建一個(gè)新的模板然后給他附上數(shù)據(jù),如果在線的話無非就是修改該空白模板id所對(duì)應(yīng)的data
public void create(HttpServletRequest request, HttpServletResponse response) throws IOException {
WorkBookEntity wb = new WorkBookEntity();
wb.setName("default");
wb.setOption(SheetUtil.getDefautOption());
WorkBookEntity saveWb = workBookRepository.save(wb);
//生成sheet數(shù)據(jù)
generateSheet(saveWb.getId());
response.sendRedirect("/index/" + saveWb.getId());
}
這是create 方法就是我用的開源庫人寫的方法 謝謝了??!
看下好像 其實(shí)沒啥咋賦值其實(shí) 可以先看下這個(gè) getDefautOption()的方法
getDefautOption() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("container", "ecsheet");
jsonObject.put("title", "ecsheet demo");
jsonObject.put("lang", "zh");
jsonObject.put("allowUpdate", true);
jsonObject.put("loadUrl", "");
jsonObject.put("loadSheetUrl", "");
jsonObject.put("updateUrl", "");
return jsonObject;
}
看到?jīng)] 其實(shí)沒啥都是默認(rèn)的,看下他們有數(shù)據(jù)的數(shù)據(jù)庫 ,
nvacat 看了下數(shù)據(jù)庫兩個(gè)表 ,workbook 很顯然 是個(gè)目錄表 就是 excel 的id
那么worksheet 就是excel數(shù)據(jù)
讓我們看下 excel的json格式(前端傳給接口的exceldata)在這里插入圖片描述
可以看出兩個(gè) 對(duì)象 info 和 sheets
那么就把方法改下文章來源:http://www.zghlxwxcb.cn/news/detail-501145.html
public static JSONObject getDefautOption(cn.hutool.json.JSONObject info) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("container", "ecsheet");
jsonObject.put("title", info.get("name").toString().replace(".xlsx", ""));
jsonObject.put("lang", "zh");
jsonObject.put("allowUpdate", true);
jsonObject.put("loadUrl", "");
jsonObject.put("loadSheetUrl", "");
jsonObject.put("updateUrl", "");
return jsonObject;
}
這一步就是創(chuàng)建個(gè)空模板然后得到個(gè)id
此時(shí)給這個(gè)id 附上對(duì)應(yīng)數(shù)據(jù)就行
看下空白模板是生成的死數(shù)據(jù)文章來源地址http://www.zghlxwxcb.cn/news/detail-501145.html
private void generateSheet(String wbId) {
SheetUtil.getDefaultSheetData().forEach(jsonObject -> {
WorkSheetEntity ws = new WorkSheetEntity();
ws.setWbId(wbId);
ws.setData(jsonObject);
ws.setDeleteStatus(0);
workSheetRepository.save(ws);
});
public static List<JSONObject> getDefaultSheetData() {
List<JSONObject> list = new ArrayList<>();
for (int i = 1; i < 4; i++) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("row", 84);
jsonObject.put("column", 60);
jsonObject.put("name", "sheet" + i);
Integer index = i - 1;
jsonObject.put("index", IdUtil.simpleUUID());
jsonObject.put("order", i - 1);
if (i == 1) {
jsonObject.put("status", 1);
} else {
jsonObject.put("status", 0);
}
jsonObject.put("celldata", new ArrayList<JSONObject>() {
});
list.add(jsonObject);
}
return list;
}
很顯然這個(gè)最后返回的list數(shù)據(jù) 就是我們的sheets 數(shù)據(jù),改寫下這不easy解決
```java
sheetJsonarry.forEach(sheet -> {
WorkSheetEntity ws = new WorkSheetEntity();
ws.setWbId(saveWb.getId());
cn.hutool.json.JSONObject jsonObjects = JSONUtil.parseObj(sheet);
ws.setData(jsonObjects);
ws.setDeleteStatus(0);
workSheetRepository.save(ws);
});
# 總結(jié)
BUG挺多導(dǎo)入按鈕完全可以移到index頁 js/sript.js 阻止了lucksheet導(dǎo)成json 目前沒有解決辦法可以解決 但是 樣式丟失index
圖表不能用
那個(gè)大牛給我加下 謝謝
保存恢復(fù)歷史解決下
免責(zé)聲明:本開源項(xiàng)目?jī)H為技術(shù)交流此一目的,嚴(yán)禁用于其他任何商業(yè)、違法犯罪、惡意攻擊等行為;
若第三者用此項(xiàng)目侵犯相關(guān)網(wǎng)站權(quán)益,一切責(zé)任自負(fù);
若本項(xiàng)目侵犯相關(guān)網(wǎng)站、個(gè)人,組織機(jī)構(gòu)權(quán)益,請(qǐng)及時(shí)聯(lián)系作者;
其實(shí)大文件上傳可以優(yōu)化一個(gè)sheet頁上傳一個(gè)sheet頁導(dǎo)入,數(shù)據(jù)頁一頁導(dǎo)入然后 合并 在一起 這樣使用的人不會(huì)有問題 但是正在渲染 怎么解決為動(dòng)態(tài)渲染 這樣就沒問題了
捐贈(zèng):
大家有空多給我的項(xiàng)目改改加點(diǎn)新功能 改好加我qq(1253799421) 我來同步
到了這里,關(guān)于基于Luckysheet實(shí)現(xiàn)的協(xié)同編輯在線表格支持在線導(dǎo)入數(shù)據(jù)庫,前端導(dǎo)出,前端導(dǎo)入,后端導(dǎo)出的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!