网站首页 编程语言 正文
1.实现加载服务器端excel文件
引入相关js
<link rel="stylesheet" href="./plugins/css/pluginsCss.css" />
<link rel="stylesheet" href="./plugins/plugins.css" />
<link rel="stylesheet" href="./css/luckysheet.css" />
<link rel="stylesheet" href="./assets/iconfont/iconfont.css" />
<script type="text/javascript" src="./jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="./js/vue.js"></script>
<script type="text/javascript" src="./lib/layui-2.5.6/layui.js"></script>
<script type="text/javascript" src="https://www.xdocin.com/xdoc.js"></script>
<script src="xlsx.full.min.js"></script>
<script type="text/javascript" src="./luckyexcel.umd.js"></script>
<script type="text/javascript" src="./luckysheet.umd.js"></script>
<script src="./plugins/js/plugin.js"></script>
luckysheet容器
<div id="luckysheet" style="margin:0px;padding:0px;width:100%;height:95vh;"></div>
获取excel并渲染
$(function () {
// 先确保获取到了xlsx文件file,再使用全局方法window.LuckyExcel转化
//预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)
let xhr = new XMLHttpRequest();
xhr.open('GET',"/file/excels/测试excel.xlsx"); //文件所在地址
xhr.responseType = 'blob';
xhr.onload = () => {
let content = xhr.response;
let blob = new Blob([content]);
let file = new File([blob],'测试excel.xlsx',{ type: 'excel/xlsx' });
console.log("file",file)
LuckyExcel.transformExcelToLucky(
file,
function (exportJson,luckysheetfile) {
// 获得转化后的表格数据后,使用luckysheet初始化,或者更新已有的luckysheet工作簿
// 注:luckysheet需要引入依赖包和初始化表格容器才可以使用
luckysheet.create({
container: 'luckysheet', //luckysheet is the container id
showinfobar: false,
lang: 'zh', // 设定表格语言
allowEdit: true,//作用:是否允许前台编辑
// allowUpdate: true,
allowCopy: true, //是否允许拷贝
showtoolbar: true, //是否第二列显示工具栏
showinfobar: true, //是否显示顶部名称栏
showsheetbar: true, //是否显示底部表格名称区域
showstatisticBar: true, //是否显示底部计数栏
pointEdit: false, //是否是编辑器插入表格模式
pointEditUpdate: null, //编辑器表格更新函数
data: exportJson.sheets,
title: exportJson.info.name,
userInfo: exportJson.info.name.creator,
});
},
function (err) {
logger.error('Import failed. Is your fail a valid xlsx?');
}
);
let formData = new FormData();
formData.append('file',file);
}
xhr.send();
})
2.文件编辑后保存
提交按钮
<button onclick="downloadCurrent()">提交</button>
提交函数
function downloadCurrent() {
var fileName = $("#luckysheet_info_detail_input").val()
fileName = (fileName + "").trim();
var sumarr =luckysheet.find("SUM",{type:"f"});
if(sumarr && sumarr.length>0){
console.log("sumarr[0].v",sumarr[0].v);
}
$.ajax({
url: '/upload_luckysheet', //接口地址
type: 'POST',
headers: { 'Content-Type': 'application/json;' },
data: JSON.stringify({
exceldatas: JSON.stringify(luckysheet.getAllSheets()),
fileName: fileName,
}),
success: function (response) {
alert("保存成功!")
}
})
}
后台接口
1)入参VO:LuckysheetParamsVo
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class LuckysheetParamsVo {
@NotBlank(message = "Luckysheet的表格数据不能为空")
@ApiModelProperty("Luckysheet的表格数据")
private String excelDatas;
@NotBlank(message = "表格名称不能为空")
@ApiModelProperty("表格名称")
private String fileName;
}
2)Controller
@PostMapping("/upload_luckysheet")
@ResponseBody
public String downData(@Valid @RequestBody LuckysheetParamsVo luckysheetParamsVo) {
//uploadFileDir 是文件上传地址
String filePath = uploadFileDir+"excels/";
String fileName = luckysheetParamsVo.getFileName();
String excelDatas = luckysheetParamsVo.getExcelDatas();
try{
luckysheetService.exportLuckySheetXlsxByPOI("", filePath,fileName,excelDatas);
} catch (Exception e) {
e.printStackTrace();
return new ReturnData(ReturnData.OPERATE_FAIL, ReturnData.SERVICE_EXCEPTION);
}
return filePath+fileName;
}
3)LuckysheetService
public interface LuckysheetService {
String exportLuckySheetXlsxByPOI(String title, String newFileDir, String newFileName, String excelData);
}
4)LuckysheetServiceImpl
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.stereotype.Service;
import java.awt.*;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
@Service
public class LuckysheetServiceImpl implements LuckysheetService {
/**
* luckysheet格式数据转excel文件并存储
* @param title
* @param newFileDir
* @param newFileName
* @param excelData
*/
@Override
public String exportLuckySheetXlsxByPOI(String title, String newFileDir, String newFileName, String excelData) {
//去除luckysheet中 
 的换行
excelData = excelData.replace("
", "\\r\\n");
//获取luckysheet数据 sheet:[{name:sheet1, ...},{}, ...]
JSONArray jsonArray = (JSONArray) JSONObject.parse(excelData);
//创建操作Excel的XSSFWorkbook对象
XSSFWorkbook excel = new XSSFWorkbook();
for (int sheetIndex = 0; sheetIndex < jsonArray.size(); sheetIndex++) {
//获取sheet
JSONObject jsonObject = (JSONObject) jsonArray.get(sheetIndex);
JSONArray celldataObjectList = jsonObject.getJSONArray("celldata");//获取所有单元格(坐标,内容,字体类型,字体大小...)
JSONArray rowObjectList = jsonObject.getJSONArray("visibledatarow");
JSONArray colObjectList = jsonObject.getJSONArray("visibledatacolumn");
JSONArray dataObjectList = jsonObject.getJSONArray("data");//获取所有单元格,与celldata类似(坐标,内容,字体类型,字体大小...)
JSONObject mergeObject = jsonObject.getJSONObject("config").getJSONObject("merge");//合并单元格
JSONObject columnlenObject = jsonObject.getJSONObject("config").getJSONObject("columnlen");//表格列宽
JSONObject rowlenObject = jsonObject.getJSONObject("config").getJSONObject("rowlen");//表格行高
JSONArray borderInfoObjectList = jsonObject.getJSONObject("config").getJSONArray("borderInfo");//边框样式
//参考:https://blog.csdn.net/jdtugfcg/article/details/84100315
XSSFCellStyle cellStyle = excel.createCellStyle();
//创建XSSFSheet对象
XSSFSheet sheet = excel.createSheet(jsonObject.getString("name"));
//如果这行没有了,整个公式都不会有自动计算的效果的
sheet.setForceFormulaRecalculation(true);
//我们都知道excel是表格,即由一行一行组成的,那么这一行在java类中就是一个XSSFRow对象,我们通过XSSFSheet对象就可以创建XSSFRow对象
//如:创建表格中的第一行(我们常用来做标题的行) XSSFRow firstRow = sheet.createRow(0); 注意下标从0开始
//根据luckysheet创建行列
//创建行和列
if (rowObjectList != null && rowObjectList.size() > 0) {
for (int i = 0; i < rowObjectList.size(); i++) {
XSSFRow row = sheet.createRow(i);//创建行
try {
//转化excle行高参数1
BigDecimal excleHei1=new BigDecimal(72);
//转化excle行高参数2
BigDecimal excleHei2=new BigDecimal(96);
row.setHeightInPoints(new BigDecimal(rowlenObject.get(i)+ "").multiply(excleHei1).divide(excleHei2).floatValue());//行高px值
} catch (Exception e) {
row.setHeightInPoints(20f);//默认行高
}
if (colObjectList != null && colObjectList.size() > 0) {
for (int j = 0; j < colObjectList.size(); j++) {
if (columnlenObject != null && columnlenObject.getInteger(j + "") != null) {
//转化excle列宽参数35.7 调试后我改为33 --具体多少没有算
BigDecimal excleWid=new BigDecimal(33);
sheet.setColumnWidth(j, new BigDecimal(rowlenObject.get(j)+ "").multiply(excleWid).setScale(0,BigDecimal.ROUND_HALF_UP).intValue());//列宽px值
}
row.createCell(j);//创建列
}
}
}
}
//设置值,样式
setCellValue(celldataObjectList, borderInfoObjectList, sheet, excel);
// 判断路径是否存在
File dir = new File(newFileDir);
if (!dir.exists()) {
dir.mkdirs();
}
OutputStream out = null;
try {
out = new FileOutputStream(newFileDir + newFileName);
excel.write(out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return newFileDir+newFileName;
}
/**
* 合并单元格与填充单元格颜色
* @param jsonObjectValue
* @param sheet
* @param style
*/
private static void setMergeAndColorByObject(JSONObject jsonObjectValue, XSSFSheet sheet, XSSFCellStyle style) {
JSONObject mergeObject = (JSONObject) jsonObjectValue.get("mc");
//合并单元格
if (mergeObject != null) {
int r = (int) (mergeObject.get("r"));
int c = (int) (mergeObject.get("c"));
if ((mergeObject.get("rs") != null && (mergeObject.get("cs") != null))) {
int rs = (int) (mergeObject.get("rs"));
int cs = (int) (mergeObject.get("cs"));
CellRangeAddress region = new CellRangeAddress(r, r + rs - 1, (short) (c), (short) (c + cs - 1));
sheet.addMergedRegion(region);
}
}
//填充颜色
if (jsonObjectValue.getString("bg") != null) {
int bg = Integer.parseInt(jsonObjectValue.getString("bg").replace("#", ""), 16);
style.setFillPattern(FillPatternType.SOLID_FOREGROUND); //设置填充方案
style.setFillForegroundColor(new XSSFColor(new Color(bg))); //设置填充颜色
}
}
private static void setBorder(JSONArray borderInfoObjectList, XSSFWorkbook workbook, XSSFSheet sheet) {
//设置边框样式map
Map<Integer, BorderStyle> bordMap = new HashMap<>();
bordMap.put(1, BorderStyle.THIN);
bordMap.put(2, BorderStyle.HAIR);
bordMap.put(3, BorderStyle.DOTTED);
bordMap.put(4, BorderStyle.DASHED);
bordMap.put(5, BorderStyle.DASH_DOT);
bordMap.put(6, BorderStyle.DASH_DOT_DOT);
bordMap.put(7, BorderStyle.DOUBLE);
bordMap.put(8, BorderStyle.MEDIUM);
bordMap.put(9, BorderStyle.MEDIUM_DASHED);
bordMap.put(10, BorderStyle.MEDIUM_DASH_DOT);
bordMap.put(11, BorderStyle.SLANTED_DASH_DOT);
bordMap.put(12, BorderStyle.THICK);
//一定要通过 cell.getCellStyle() 不然的话之前设置的样式会丢失
//设置边框
if (borderInfoObjectList != null && borderInfoObjectList.size() > 0) {
for (int i = 0; i < borderInfoObjectList.size(); i++) {
JSONObject borderInfoObject = (JSONObject) borderInfoObjectList.get(i);
if (borderInfoObject.get("rangeType").equals("cell")) {//单个单元格
JSONObject borderValueObject = borderInfoObject.getJSONObject("value");
JSONObject l = borderValueObject.getJSONObject("l");
JSONObject r = borderValueObject.getJSONObject("r");
JSONObject t = borderValueObject.getJSONObject("t");
JSONObject b = borderValueObject.getJSONObject("b");
int row = borderValueObject.getInteger("row_index");
int col = borderValueObject.getInteger("col_index");
XSSFCell cell = sheet.getRow(row).getCell(col);
if (l != null) {
cell.getCellStyle().setBorderLeft(bordMap.get((int) l.get("style"))); //左边框
int bg = Integer.parseInt(l.getString("color").replace("#", ""), 16);
cell.getCellStyle().setLeftBorderColor(new XSSFColor(new Color(bg)));//左边框颜色
}
if (r != null) {
cell.getCellStyle().setBorderRight(bordMap.get((int) r.get("style"))); //右边框
int bg = Integer.parseInt(r.getString("color").replace("#", ""), 16);
cell.getCellStyle().setRightBorderColor(new XSSFColor(new Color(bg)));//右边框颜色
}
if (t != null) {
cell.getCellStyle().setBorderTop(bordMap.get((int) t.get("style"))); //顶部边框
int bg = Integer.parseInt(t.getString("color").replace("#", ""), 16);
cell.getCellStyle().setTopBorderColor(new XSSFColor(new Color(bg)));//顶部边框颜色
}
if (b != null) {
cell.getCellStyle().setBorderBottom(bordMap.get((int) b.get("style"))); //底部边框
int bg = Integer.parseInt(b.getString("color").replace("#", ""), 16);
cell.getCellStyle().setBottomBorderColor(new XSSFColor(new Color(bg)));//底部边框颜色
}
} else if (borderInfoObject.get("rangeType").equals("range")) {//选区
int bg_ = Integer.parseInt(borderInfoObject.getString("color").replace("#", ""), 16);
int style_ = borderInfoObject.getInteger("style");
JSONObject rangObject = (JSONObject) ((JSONArray) (borderInfoObject.get("range"))).get(0);
JSONArray rowList = rangObject.getJSONArray("row");
JSONArray columnList = rangObject.getJSONArray("column");
for (int row_ = rowList.getInteger(0); row_ < rowList.getInteger(rowList.size() - 1) + 1; row_++) {
for (int col_ = columnList.getInteger(0); col_ < columnList.getInteger(columnList.size() - 1) + 1; col_++) {
XSSFCell cell = sheet.getRow(row_).getCell(col_);
cell.getCellStyle().setBorderLeft(bordMap.get(style_)); //左边框
cell.getCellStyle().setLeftBorderColor(new XSSFColor(new Color(bg_)));//左边框颜色
cell.getCellStyle().setBorderRight(bordMap.get(style_)); //右边框
cell.getCellStyle().setRightBorderColor(new XSSFColor(new Color(bg_)));//右边框颜色
cell.getCellStyle().setBorderTop(bordMap.get(style_)); //顶部边框
cell.getCellStyle().setTopBorderColor(new XSSFColor(new Color(bg_)));//顶部边框颜色
cell.getCellStyle().setBorderBottom(bordMap.get(style_)); //底部边框
cell.getCellStyle().setBottomBorderColor(new XSSFColor(new Color(bg_)));//底部边框颜色 }
}
}
}
}
}
}
/**
* 設置值和樣式
* @param jsonObjectList
* @param borderInfoObjectList
* @param sheet
* @param workbook
*/
private static void setCellValue(JSONArray jsonObjectList, JSONArray borderInfoObjectList, XSSFSheet
sheet, XSSFWorkbook workbook) {
for (int index = 0; index < jsonObjectList.size(); index++) {
XSSFCellStyle style = workbook.createCellStyle();//样式
XSSFFont font = workbook.createFont();//字体样式
JSONObject object = jsonObjectList.getJSONObject(index);
String str_ = (int) object.get("r") + "_" + object.get("c") + "=" + ((JSONObject) object.get("v")).get("v") + "\n";
JSONObject jsonObjectValue = ((JSONObject) object.get("v"));//獲取單元格樣式
String value = "";
String t = ""; // t为excel内容的格式 (n:数值类型)
if (jsonObjectValue != null ) {
if (jsonObjectValue.get("v") != null){
value = jsonObjectValue.getString("v");
}
if (jsonObjectValue.get("ct") != null){
JSONObject jsonObject = ((JSONObject) jsonObjectValue.get("ct"));
if (jsonObject.get("t") != null){
t = jsonObject.getString("t");
}
}
}
if (sheet.getRow((int) object.get("r")) != null && sheet.getRow((int) object.get("r")).getCell((int) object.get("c")) != null) {
XSSFCell cell = sheet.getRow((int) object.get("r")).getCell((int) object.get("c"));
if (jsonObjectValue != null && jsonObjectValue.get("f") != null) {//如果有公式,设置公式
String f = jsonObjectValue.getString("f");
cell.setCellFormula(f.substring(1,f.length()));//不需要=符号,例:INT(12.3)
//填充值
cell.setCellValue(value);
}else {
switch(t){
case "n":
cell.setCellValue(Double.valueOf(value));
break;
default:
cell.setCellValue(value);
}
// if (StringUtils.isNotEmpty(t)){
// if (t.equals("n")){
// cell.setCellValue(Double.valueOf(value));
// }else {
// cell.setCellValue(value);
// }
// }else {
// cell.setCellValue(value);
// }
}
//合并单元格与填充单元格颜色
setMergeAndColorByObject(jsonObjectValue, sheet, style);
//填充值
XSSFRow row = sheet.getRow((int) object.get("r"));
//设置垂直水平对齐方式
int vt = jsonObjectValue.getInteger("vt") == null ? 1 : jsonObjectValue.getInteger("vt");//垂直对齐 0 中间、1 上、2下
int ht = jsonObjectValue.getInteger("ht") == null ? 1 : jsonObjectValue.getInteger("ht");//0 居中、1 左、2右
switch (vt) {
case 0:
style.setVerticalAlignment(VerticalAlignment.CENTER);
break;
case 1:
style.setVerticalAlignment(VerticalAlignment.TOP);
break;
case 2:
style.setVerticalAlignment(VerticalAlignment.BOTTOM);
break;
}
switch (ht) {
case 0:
style.setAlignment(HorizontalAlignment.CENTER);
break;
case 1:
style.setAlignment(HorizontalAlignment.LEFT);
break;
case 2:
style.setAlignment(HorizontalAlignment.RIGHT);
break;
}
//设置合并单元格的样式有问题
String ff = jsonObjectValue.getString("ff");//0 Times New Roman、 1 Arial、2 Tahoma 、3 Verdana、4 微软雅黑、5 宋体(Song)、6 黑体(ST Heiti)、7 楷体(ST Kaiti)、 8 仿宋(ST FangSong)、9 新宋体(ST Song)、10 华文新魏、11 华文行楷、12 华文隶书
int fs = jsonObjectValue.getInteger("fs") == null ? 14 : jsonObjectValue.getInteger("fs");//字体大小
int bl = jsonObjectValue.getInteger("bl") == null ? 0 : jsonObjectValue.getInteger("bl");//粗体 0 常规 、 1加粗
int it = jsonObjectValue.getInteger("it") == null ? 0 : jsonObjectValue.getInteger("it");//斜体 0 常规 、 1 斜体
String fc = jsonObjectValue.getString("fc") == null ? "" : jsonObjectValue.getString("fc");//字体颜色
// font.setFontName(fontMap.get(ff));//字体名字
//字體顏色
if (fc.length() > 0) {
font.setColor(new XSSFColor(new Color(Integer.parseInt(fc.replace("#", ""), 16))));
}
font.setFontName(ff);//字体名字
font.setFontHeightInPoints((short) fs);//字体大小
//是否粗體
if (bl == 1) {
font.setBold(true);//粗体显示
}
//是否斜體
font.setItalic(it == 1 ? true : false);//斜体
style.setFont(font);
style.setWrapText(true);//设置自动换行
cell.setCellStyle(style);
} else {
System.out.println("错误的=" + index + ">>>" + str_);
}
}
//设置边框
setBorder(borderInfoObjectList, workbook, sheet);
}
}
期间遇到的问题
1.修改后的excel文件打开发现sum函数未保存进去
解决方案:在上面exportLuckySheetXlsxByPOI方法中创建XSSFSheet对象之后设置sheet.setForceFormulaRecalculation(true);
2.保存之后的excel文件中所有的值均为字符串类型,导致sum函数为0
解决方案:在上面setCellValue方法中往excel对象写值时指定其格式
这里的“n”对应得Luckysheet单元格值格式的数字类型
3.保存之后发现在excel文件中单元格的高度和宽度便大了,排查问题的时候也发现写入文件之前设置的高度和宽度值都没有发生变化,写入到excel中才会变大,网上寻找答案时无意中发现有个博客中记载着转换方式:博客地址
将创建excel的行和列代码更改后发现问题解决:
原创建行和列代码:
if (rowObjectList != null && rowObjectList.size() > 0) {
for (int i = 0; i < rowObjectList.size(); i++) {
XSSFRow row = sheet.createRow(i);//创建行
try {
row.setHeightInPoints(Float.parseFloat(rowlenObject.get(i) + ""));//行高px值
} catch (Exception e) {
row.setHeightInPoints(20f);//默认行高
}
if (colObjectList != null && colObjectList.size() > 0) {
for (int j = 0; j < colObjectList.size(); j++) {
if (columnlenObject != null && columnlenObject.getInteger(j + "") != null) {
sheet.setColumnWidth(j, columnlenObject.getInteger(j + "") * 42);//列宽px值
}
row.createCell(j);//创建列
}
}
}
}
通过转换创建行和列代码:
if (rowObjectList != null && rowObjectList.size() > 0) {
for (int i = 0; i < rowObjectList.size(); i++) {
XSSFRow row = sheet.createRow(i);//创建行
try {
//转化excle行高参数1
BigDecimal excleHei1=new BigDecimal(72);
//转化excle行高参数2
BigDecimal excleHei2=new BigDecimal(96);
row.setHeightInPoints(new BigDecimal(rowlenObject.get(i)+ "").multiply(excleHei1).divide(excleHei2).floatValue());//行高px值
} catch (Exception e) {
row.setHeightInPoints(20f);//默认行高
}
if (colObjectList != null && colObjectList.size() > 0) {
for (int j = 0; j < colObjectList.size(); j++) {
if (columnlenObject != null && columnlenObject.getInteger(j + "") != null) {
//转化excle列宽参数35.7 调试后我改为33 --具体多少没有算
BigDecimal excleWid=new BigDecimal(33);
sheet.setColumnWidth(j, new BigDecimal(rowlenObject.get(j)+ "").multiply(excleWid).setScale(0,BigDecimal.ROUND_HALF_UP).intValue());//列宽px值
row.createCell(j);//创建列
}
row.createCell(j);//创建列
}
}
}
}
4.使用luckysheet.find(“SUM”,{type:“f”})函数查找返回空的问题
解决方案:我这里的原因是因为luckysheet.umd.js的版本不是最新版导致的,更换最新版发现问题解决
其他
Luckysheet中的一些函数:
hook: {
cellDragStop: function (cell, postion, sheetFile, ctx, event) {
// console.info(cell, postion, sheetFile, ctx, event);
},
rowTitleCellRenderBefore: function (rowNum, postion, ctx) {
// console.log(rowNum);
},
rowTitleCellRenderAfter: function (rowNum, postion, ctx) {
// console.log(ctx);
},
columnTitleCellRenderBefore: function (columnAbc, postion, ctx) {
// console.log(columnAbc);
},
columnTitleCellRenderAfter: function (columnAbc, postion, ctx) {
// console.log(postion);
},
cellRenderBefore: function (cell, postion, sheetFile, ctx) {
// console.log(cell,postion,sheetFile,ctx);
},
cellRenderAfter: function (cell, postion, sheetFile, ctx) {
// console.log(postion);
},
cellMousedownBefore: function (cell, postion, sheetFile, ctx) {
// console.log(postion);
},
cellMousedown: function (cell, postion, sheetFile, ctx) {
// console.log(sheetFile);
},
sheetMousemove: function (cell, postion, sheetFile, moveState, ctx) {
// console.log(cell,postion,sheetFile,moveState,ctx);
},
sheetMouseup: function (cell, postion, sheetFile, moveState, ctx) {
// console.log(cell,postion,sheetFile,moveState,ctx);
},
cellAllRenderBefore: function (data, sheetFile, ctx) {
// console.info(data,sheetFile,ctx)
},
updated: function (operate) {
// console.info(operate)
},
cellUpdateBefore: function (r, c, value, isRefresh) {
// console.info('cellUpdateBefore',r,c,value,isRefresh)
},
cellUpdated: function (r, c, oldValue, newValue, isRefresh) {
// console.info('cellUpdated',r,c,oldValue, newValue, isRefresh)
},
sheetActivate: function (index, isPivotInitial, isNewSheet) {
// console.info(index, isPivotInitial, isNewSheet)
},
rangeSelect: function (index, sheet) {
// console.info(index, sheet)
},
commentInsertBefore: function (r, c) {
// console.info(r, c)
},
commentInsertAfter: function (r, c, cell) {
// console.info(r, c, cell)
},
commentDeleteBefore: function (r, c, cell) {
// console.info(r, c, cell)
},
commentDeleteAfter: function (r, c, cell) {
// console.info(r, c, cell)
},
commentUpdateBefore: function (r, c, value) {
// console.info(r, c, value)
},
commentUpdateAfter: function (r, c, oldCell, newCell) {
// console.info(r, c, oldCell, newCell)
},
cellEditBefore: function (range) {
// console.info(range)
},
workbookCreateAfter: function (json) {
// console.info(json)
},
rangePasteBefore: function (range, data) {
// console.info('rangePasteBefore',range,data)
// return false; //Can intercept paste
},
}
例如:
DEMO地址:
链接:https://pan.baidu.com/s/1fa_4mGnKiH_TOXi0OlKR6g?pwd=7pcy
提取码:7pcy
下载demo然后解压,放置D盘根目录下
启动其中的Java代码
运行nginx-Luckysheet文件夹下的luckysheet.exe
访问 http://localhost:8088/web/
原文链接:https://blog.csdn.net/YXWik/article/details/125207633
- 上一篇:eureka更换为nacos
- 下一篇:ui追加动态li
相关推荐
- 2022-11-04 详解Pytorch中的tensor数据结构_python
- 2024-01-28 spring自动配置的原理
- 2022-12-31 React实现合成事件的源码分析_React
- 2022-06-08 记录一次奇怪的springboot cache redis缓存报错解决
- 2022-06-12 C#集合之有序列表的用法_C#教程
- 2022-08-28 本周遇到的一些问题整理,有些未完全解决,留在下周写
- 2022-03-23 C语言利用system调用系统命令行详情_C 语言
- 2023-09-12 SpringBoot整合MQTT(MqttClient)
- 最近更新
-
- window11 系统安装 yarn
- 超详细win安装深度学习环境2025年最新版(
- Linux 中运行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存储小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基础操作-- 运算符,流程控制 Flo
- 1. Int 和Integer 的区别,Jav
- spring @retryable不生效的一种
- Spring Security之认证信息的处理
- Spring Security之认证过滤器
- Spring Security概述快速入门
- Spring Security之配置体系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置权
- redisson分布式锁中waittime的设
- maven:解决release错误:Artif
- restTemplate使用总结
- Spring Security之安全异常处理
- MybatisPlus优雅实现加密?
- Spring ioc容器与Bean的生命周期。
- 【探索SpringCloud】服务发现-Nac
- Spring Security之基于HttpR
- Redis 底层数据结构-简单动态字符串(SD
- arthas操作spring被代理目标对象命令
- Spring中的单例模式应用详解
- 聊聊消息队列,发送消息的4种方式
- bootspring第三方资源配置管理
- GIT同步修改后的远程分支