|
|
@@ -192,7 +192,7 @@ public class GrapeCityController {
|
|
|
throw new IllegalArgumentException("请求参数不能为空");
|
|
|
}
|
|
|
|
|
|
- logger.debug("收到 pdf 请求:{}", request);
|
|
|
+// logger.debug("收到 pdf 请求:{}", request);
|
|
|
|
|
|
// 转换 templateBytes
|
|
|
byte[] templateBytes = convertToByteArray(request.get("templateBytes"), "templateBytes");
|
|
|
@@ -216,8 +216,31 @@ public class GrapeCityController {
|
|
|
workbook = new Workbook(workbookOptions);
|
|
|
inputStream = new ByteArrayInputStream(templateBytes);
|
|
|
workbook.open(inputStream, OpenFileFormat.Sjs);
|
|
|
+
|
|
|
+ // 先处理续页(此时模板还未展开,toJson 捕获的是模板结构)
|
|
|
+ boolean continuePage = false;
|
|
|
+ String copyConfigJson = null;
|
|
|
+ try {
|
|
|
+ continuePage = request.get("continuePage") != null && Boolean.parseBoolean(request.get("continuePage").toString());
|
|
|
+ copyConfigJson = request.get("copyConfig") != null
|
|
|
+ ? request.get("copyConfig").toString()
|
|
|
+ : null;
|
|
|
+ List<String> newColCodes = new ArrayList<>();
|
|
|
+ List<String> existingColCodes = extractStringList(request.get("existingColCodes"));
|
|
|
+ logger.info("[fullPdf] continuePage={}, copyConfigJson={}, dataKeys={}, sheetCount={}",
|
|
|
+ continuePage, copyConfigJson != null, data != null ? data.size() : 0,
|
|
|
+ workbook.getWorksheets().getCount());
|
|
|
+ if (continuePage && copyConfigJson != null) {
|
|
|
+ workbook = handleContinuationPages(workbook, copyConfigJson, existingColCodes, newColCodes, data);
|
|
|
+ logger.info("[fullPdf] handleContinuationPages 完成, sheetCount={}", workbook.getWorksheets().getCount());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("处理分页异常:{}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
for (int i = 0; i < workbook.getWorksheets().getCount(); i++) {
|
|
|
IWorksheet worksheet = workbook.getWorksheets().get(i);
|
|
|
+ logger.info("[fullPdf] 处理 sheet[{}]: {}", i, worksheet.getName());
|
|
|
worksheet.getPageSetup().setPrintHeadings(false);
|
|
|
worksheet.getPageSetup().setPaperSize(PaperSize.A4);
|
|
|
worksheet.getPageSetup().setLeftMargin(7); // 左边距
|
|
|
@@ -226,9 +249,67 @@ public class GrapeCityController {
|
|
|
worksheet.getUsedRange().setShrinkToFit(true);
|
|
|
// 在 setDataSource 前收集表格第一行数据行的合并单元格规则(setDataSource 会将已有合并拆开)
|
|
|
Map<ITable, List<int[]>> tableMergeInfo = collectTableMergeInfo(worksheet);
|
|
|
- worksheet.setDataSource(new JsonDataSource(JSON.toJSONString(data)));
|
|
|
+
|
|
|
+ boolean isContinuationSheet = worksheet.getName().contains(" (");
|
|
|
+
|
|
|
+ if (!isContinuationSheet) {
|
|
|
+ worksheet.setDataSource(new JsonDataSource(JSON.toJSONString(data)));
|
|
|
+ }
|
|
|
+
|
|
|
+ fillCellsByBindingPath(worksheet, data);
|
|
|
+
|
|
|
// 数据源绑定后,将第一行数据行的样式、行高、合并规则复制到所有自动扩展的数据行
|
|
|
- copyTableRowStyles(worksheet, tableMergeInfo);
|
|
|
+ if (!isContinuationSheet) {
|
|
|
+ copyTableRowStyles(worksheet, tableMergeInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 续页填写值后验证数据存在
|
|
|
+ if (isContinuationSheet) {
|
|
|
+ int nonEmptyCount = 0;
|
|
|
+ for (int r = 0; r < worksheet.getRowCount() && nonEmptyCount < 5; r++) {
|
|
|
+ for (int c = 0; c < worksheet.getColumnCount() && nonEmptyCount < 5; c++) {
|
|
|
+ Object val = worksheet.getRange(r, c).getValue();
|
|
|
+ if (val != null && !val.toString().isEmpty()) {
|
|
|
+ nonEmptyCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ logger.info("[fullPdf] 续页 {} 数据校验: 前5个非空值={}", worksheet.getName(), nonEmptyCount);
|
|
|
+ }
|
|
|
+
|
|
|
+ // hidden 检查:数据填充后判断原始续页是否为空,空则隐藏
|
|
|
+ if (continuePage && copyConfigJson != null && !isContinuationSheet) {
|
|
|
+ try {
|
|
|
+ JSONObject cc = JSON.parseObject(copyConfigJson);
|
|
|
+ String ccSheetName = cc.getString("sheetName");
|
|
|
+ Boolean ccHidden = cc.getBoolean("hidden");
|
|
|
+ if (Boolean.TRUE.equals(ccHidden) && ccSheetName != null && ccSheetName.equals(worksheet.getName())) {
|
|
|
+ JSONObject cr = cc.getJSONObject("copyRange");
|
|
|
+ if (cr != null) {
|
|
|
+ String[] tls = cr.getString("topLeft").split(",");
|
|
|
+ String[] trs = cr.getString("topRight").split(",");
|
|
|
+ int ccCol = Integer.parseInt(tls[0]);
|
|
|
+ int ccRow = Integer.parseInt(tls[1]);
|
|
|
+ int ccColCount = Integer.parseInt(trs[0]) - ccCol;
|
|
|
+ boolean isEmpty = true;
|
|
|
+ for (int k = 0; k <= ccColCount; k++) {
|
|
|
+ Object cv = worksheet.getRange(ccRow, ccCol + k).getValue();
|
|
|
+ if (cv != null && !cv.toString().isEmpty()) {
|
|
|
+ isEmpty = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ logger.info("[fullPdf] hidden 检查 sheet={}, isEmpty={}", worksheet.getName(), isEmpty);
|
|
|
+ if (isEmpty) {
|
|
|
+ worksheet.setVisible(Visibility.Hidden);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.warn("[fullPdf] hidden 检查异常: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (!worksheet.getName().contains("封面") && !worksheet.getName().contains("注意")) {
|
|
|
worksheet.getPageSetup().setIsAutoFirstPageNumber(true);
|
|
|
}
|
|
|
@@ -239,20 +320,6 @@ public class GrapeCityController {
|
|
|
// 浮动图片
|
|
|
processFloatingImages(worksheet, data, fileBytes);
|
|
|
}
|
|
|
- try {
|
|
|
- boolean continuePage = request.get("continuePage") != null && Boolean.parseBoolean(request.get("continuePage").toString());
|
|
|
- String copyConfigJson = request.get("copyConfig") != null
|
|
|
- ? request.get("copyConfig").toString()
|
|
|
- : null;
|
|
|
- List<String> newColCodes = new ArrayList<>();
|
|
|
- List<String> existingColCodes = extractStringList(request.get("existingColCodes"));
|
|
|
- if (continuePage && copyConfigJson != null) {
|
|
|
- workbook = handleContinuationPages(workbook, copyConfigJson, existingColCodes, newColCodes);
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error("处理分页异常:{}", e.getMessage());
|
|
|
- }
|
|
|
-
|
|
|
PrintManager printManager = new PrintManager();
|
|
|
//Workbook.FontsFolderPath = this.fontsFolderPath;
|
|
|
Workbook.FontProvider = new IFontProvider() {
|
|
|
@@ -419,12 +486,18 @@ public class GrapeCityController {
|
|
|
* copyConfigJson 和 existingColCodes 由 pressure2 传入,newColCodes 通过参数返回给调用方
|
|
|
*/
|
|
|
private Workbook handleContinuationPages(Workbook workbook, String copyConfigJson,
|
|
|
- List<String> existingColCodes, List<String> newColCodes) {
|
|
|
+ List<String> existingColCodes, List<String> newColCodes,
|
|
|
+ Map<String, Object> data) {
|
|
|
try {
|
|
|
+ logger.info("[handleContinuationPages] 进入, sheetCount={}, dataKeys={}",
|
|
|
+ workbook.getWorksheets().getCount(), data != null ? data.size() : 0);
|
|
|
JSONObject copyConfig = JSON.parseObject(copyConfigJson);
|
|
|
|
|
|
Boolean isContinuePage = copyConfig.getBoolean("isContinuePage");
|
|
|
- if (!Boolean.TRUE.equals(isContinuePage)) return workbook;
|
|
|
+ if (!Boolean.TRUE.equals(isContinuePage)) {
|
|
|
+ logger.info("[handleContinuationPages] isContinuePage=false, 跳过");
|
|
|
+ return workbook;
|
|
|
+ }
|
|
|
|
|
|
String sheetName = copyConfig.getString("sheetName");
|
|
|
if (sheetName == null) return workbook;
|
|
|
@@ -440,9 +513,8 @@ public class GrapeCityController {
|
|
|
int row = Integer.parseInt(topLeft[1]);
|
|
|
int colCount = Integer.parseInt(topRight[0]) - col;
|
|
|
int rowCount = Integer.parseInt(bottomLeft[1]) - row;
|
|
|
+ int rowsPerPage = rowCount + 1;
|
|
|
|
|
|
- WorkbookOptions workbookOptions = new WorkbookOptions();
|
|
|
- workbookOptions.setPixelBasedColumnWidth(true);
|
|
|
IWorksheet targetSheet = null;
|
|
|
for (int i = 0; i < workbook.getWorksheets().getCount(); i++) {
|
|
|
if (workbook.getWorksheets().get(i).getName().equals(sheetName)) {
|
|
|
@@ -452,42 +524,79 @@ public class GrapeCityController {
|
|
|
}
|
|
|
if (targetSheet == null) return workbook;
|
|
|
|
|
|
- Boolean hidden = copyConfig.getBoolean("hidden");
|
|
|
- if (Boolean.TRUE.equals(hidden)) {
|
|
|
- boolean isEmpty = true;
|
|
|
- for (int i = 0; i <= colCount; i++) {
|
|
|
- Object cellValue = targetSheet.getRange(row, col + i).getValue();
|
|
|
- if (cellValue != null && !cellValue.toString().isEmpty()) {
|
|
|
- isEmpty = false;
|
|
|
- break;
|
|
|
+ // 提前捕获模板 JSON(在 hidden 检查前,避免捕获隐藏状态),去掉 name/visible 防止 fromJson 冲突
|
|
|
+ String templateSheetJson = targetSheet.toJson();
|
|
|
+ JSONObject templateJsonObj = JSON.parseObject(templateSheetJson);
|
|
|
+ templateJsonObj.remove("name");
|
|
|
+ templateJsonObj.remove("visible");
|
|
|
+ String strippedJson = templateJsonObj.toJSONString();
|
|
|
+
|
|
|
+ // 扫描 copyRange 找出所有前缀组和最小索引 (copyMinIndex)
|
|
|
+ int copyMinIndex = Integer.MAX_VALUE;
|
|
|
+ Set<String> prefixes = new HashSet<>();
|
|
|
+ java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("^(.+)_(\\d+)$");
|
|
|
+ for (int i = 0; i <= colCount; i++) {
|
|
|
+ for (int j = 0; j <= rowCount; j++) {
|
|
|
+ String bp = targetSheet.getRange(row + j, col + i).getBindingPath();
|
|
|
+ if (bp != null) {
|
|
|
+ java.util.regex.Matcher matcher = pattern.matcher(bp);
|
|
|
+ if (matcher.find()) {
|
|
|
+ prefixes.add(matcher.group(1) + "_");
|
|
|
+ int num = Integer.parseInt(matcher.group(2));
|
|
|
+ if (num < copyMinIndex) copyMinIndex = num;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- if (isEmpty) {
|
|
|
- targetSheet.setVisible(Visibility.Hidden);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 后端同步前端 distributeArrayFieldToCells:将 prefix_1 中保存的全量数组拆成 prefix_1...prefix_N
|
|
|
+ int maxArrayLen = expandArrayFieldsForContinuation(data, prefixes);
|
|
|
+ logger.info("[handleContinuationPages] expandArrayFieldsForContinuation 完成, maxArrayLen={}", maxArrayLen);
|
|
|
+
|
|
|
+ // 兼容已经是 prefix_1...prefix_N 形式的数据
|
|
|
+ if (data != null && !data.isEmpty()) {
|
|
|
+ for (String prefix : prefixes) {
|
|
|
+ int localMax = 0;
|
|
|
+ for (String key : data.keySet()) {
|
|
|
+ if (key.startsWith(prefix)) {
|
|
|
+ try {
|
|
|
+ int num = Integer.parseInt(key.substring(prefix.length()));
|
|
|
+ if (num > localMax) localMax = num;
|
|
|
+ } catch (NumberFormatException ignored) {}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ logger.info("[handleContinuationPages] prefix={}, 兼容扫描得到 maxIndex={}", prefix, localMax);
|
|
|
+ if (localMax > maxArrayLen) maxArrayLen = localMax;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- List<String> effectiveExistingColCodes = existingColCodes != null ? existingColCodes : new ArrayList<>();
|
|
|
+ logger.info("[handleContinuationPages] copyMinIndex={}, rowsPerPage={}, maxArrayLen={}, prefixes={}",
|
|
|
+ copyMinIndex, rowsPerPage, maxArrayLen, prefixes);
|
|
|
|
|
|
- int sheetNum = 2;
|
|
|
+ List<String> effectiveExistingColCodes = existingColCodes != null ? existingColCodes : new ArrayList<>();
|
|
|
|
|
|
- boolean isNotEmpty = false;
|
|
|
- for (int i = 0; i <= colCount; i++) {
|
|
|
- Object cellValue = targetSheet.getRange(row + rowCount, col + i).getValue();
|
|
|
- if (cellValue != null && !cellValue.toString().isEmpty()) {
|
|
|
- isNotEmpty = true;
|
|
|
- break;
|
|
|
+ // 先固定总页数,再生成续页,避免生成过程中 workbook/sheet 状态影响循环判断
|
|
|
+ int totalPages = 1;
|
|
|
+ if (copyMinIndex < Integer.MAX_VALUE && maxArrayLen > 0) {
|
|
|
+ while (maxArrayLen > (copyMinIndex - 1) + totalPages * rowsPerPage) {
|
|
|
+ logger.info("[handleContinuationPages] totalPages while 循环: totalPages={}, usedSoFar={}, maxArrayLen={}",
|
|
|
+ totalPages, (copyMinIndex - 1) + totalPages * rowsPerPage, maxArrayLen);
|
|
|
+ totalPages++;
|
|
|
}
|
|
|
}
|
|
|
+ logger.info("[handleContinuationPages] totalPages={}, continuationPages={}, beforeLoopSheetCount={}",
|
|
|
+ totalPages, Math.max(0, totalPages - 1), workbook.getWorksheets().getCount());
|
|
|
|
|
|
- if (isNotEmpty) {
|
|
|
- generateContinuedSheet(workbook, targetSheet, sheetName, sheetNum,
|
|
|
- col, row, colCount, rowCount, effectiveExistingColCodes, newColCodes);
|
|
|
- sheetNum++;
|
|
|
+ for (int pageNo = 2; pageNo <= totalPages; pageNo++) {
|
|
|
+ logger.info("[handleContinuationPages] 生成续页 pageNo={}", pageNo);
|
|
|
+ try {
|
|
|
+ generateContinuedSheet(workbook, strippedJson, sheetName, pageNo,
|
|
|
+ col, row, colCount, rowCount, effectiveExistingColCodes, newColCodes, data);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("[handleContinuationPages] 生成续页失败 pageNo={}", pageNo, e);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
- workbook.save(outputStream, SaveFileFormat.Sjs);
|
|
|
return workbook;
|
|
|
} catch (Exception e) {
|
|
|
logger.warn("续页处理失败,回退返回原始 SJS", e);
|
|
|
@@ -495,39 +604,103 @@ public class GrapeCityController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private int expandArrayFieldsForContinuation(Map<String, Object> data, Set<String> prefixes) {
|
|
|
+ if (data == null || data.isEmpty() || prefixes == null || prefixes.isEmpty()) return 0;
|
|
|
+
|
|
|
+ int maxArrayLen = 0;
|
|
|
+ for (String prefix : prefixes) {
|
|
|
+ Object fullArrayObj = null;
|
|
|
+ for (int i = 0; i <= 1000; i++) {
|
|
|
+ Object candidate = data.get(prefix + i);
|
|
|
+ if (candidate instanceof List<?> list && !list.isEmpty()) {
|
|
|
+ fullArrayObj = list;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (candidate instanceof JSONArray arr && !arr.isEmpty()) {
|
|
|
+ fullArrayObj = arr;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONArray fullArray = toJSONArray(fullArrayObj);
|
|
|
+ if (fullArray == null || fullArray.isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ maxArrayLen = Math.max(maxArrayLen, fullArray.size());
|
|
|
+ for (int i = 0; i < fullArray.size(); i++) {
|
|
|
+ data.put(prefix + (i + 1), fullArray.get(i));
|
|
|
+ }
|
|
|
+ logger.info("[expandArrayFieldsForContinuation] prefix={}, fullArrayLen={}", prefix, fullArray.size());
|
|
|
+ }
|
|
|
+ return maxArrayLen;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 生成续页工作表:复制 sheet 并调整绑定路径
|
|
|
* 新字段编码通过 newColCodes 参数返回给调用方
|
|
|
*/
|
|
|
- private void generateContinuedSheet(Workbook workbook, IWorksheet sourceSheet,
|
|
|
- String sheetName, int sheetNum,
|
|
|
+ private void generateContinuedSheet(Workbook workbook, String templateJson,
|
|
|
+ String sheetName, int pageNo,
|
|
|
int col, int row, int colCount, int rowCount,
|
|
|
- List<String> existingColCodes, List<String> newColCodes) {
|
|
|
- String sheetJson = sourceSheet.toJson();
|
|
|
+ List<String> existingColCodes, List<String> newColCodes,
|
|
|
+ Map<String, Object> data) {
|
|
|
+ logger.info("[generateContinuedSheet] 开始 pageNo={}, beforeAddSheetCount={}", pageNo, workbook.getWorksheets().getCount());
|
|
|
IWorksheet newSheet = workbook.getWorksheets().add();
|
|
|
- newSheet.fromJson(sheetJson);
|
|
|
- String newSheetName = sheetName + " (" + sheetNum + ")";
|
|
|
+ logger.info("[generateContinuedSheet] add 后 sheetCount={}", workbook.getWorksheets().getCount());
|
|
|
+ newSheet.fromJson(templateJson);
|
|
|
+ logger.info("[generateContinuedSheet] fromJson 后 sheetCount={}", workbook.getWorksheets().getCount());
|
|
|
+ String newSheetName = sheetName + " (" + pageNo + ")";
|
|
|
newSheet.setName(newSheetName);
|
|
|
|
|
|
+ // 解绑新 sheet 上的 table,防止后续 setDataSource 按全量数组重新展开
|
|
|
+ if (newSheet.getTables() != null) {
|
|
|
+ int tableCount = newSheet.getTables().getCount();
|
|
|
+ logger.info("[generateContinuedSheet] pageNo={}, 发现 table 数={}", pageNo, tableCount);
|
|
|
+ for (int t = 0; t < tableCount; t++) {
|
|
|
+ ITable table = newSheet.getTables().get(t);
|
|
|
+ IRange tableRange = table.getRange();
|
|
|
+ boolean inRange = tableRange.getRow() <= row + rowCount && row <= tableRange.getRow() + tableRange.getRowCount() - 1;
|
|
|
+ logger.info("[generateContinuedSheet] pageNo={}, table[{}] range=[{},{},{},{}] inRange={}",
|
|
|
+ pageNo, t, tableRange.getRow(), tableRange.getColumn(),
|
|
|
+ tableRange.getRowCount(), tableRange.getColumnCount(), inRange);
|
|
|
+ if (inRange) {
|
|
|
+ table.setBindingPath(null);
|
|
|
+ logger.info("[generateContinuedSheet] pageNo={}, 解绑 table: {}", pageNo, table.getName() != null ? table.getName() : "(unnamed)");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ logger.info("[generateContinuedSheet] pageNo={}, 无 table 对象", pageNo);
|
|
|
+ }
|
|
|
+
|
|
|
+ int rowsPerPage = rowCount + 1;
|
|
|
+ int bindingPathModCount = 0;
|
|
|
for (int i = 0; i <= colCount; i++) {
|
|
|
for (int j = 0; j <= rowCount; j++) {
|
|
|
- String bindingPath = sourceSheet.getRange(row + j, col + i).getBindingPath();
|
|
|
+ String bindingPath = newSheet.getRange(row + j, col + i).getBindingPath();
|
|
|
if (bindingPath != null && bindingPath.contains("_")) {
|
|
|
String prefix = bindingPath.substring(0, bindingPath.lastIndexOf("_") + 1);
|
|
|
String numStr = bindingPath.substring(bindingPath.lastIndexOf("_") + 1);
|
|
|
try {
|
|
|
int num = Integer.parseInt(numStr);
|
|
|
- int newNum = num + (rowCount + 1) * (sheetNum - 1);
|
|
|
+ int newNum = num + rowsPerPage * (pageNo - 1);
|
|
|
String newPath = prefix + newNum;
|
|
|
newSheet.getRange(row + j, col + i).setBindingPath(newPath);
|
|
|
if (!existingColCodes.contains(newPath) && !newColCodes.contains(newPath)) {
|
|
|
newColCodes.add(newPath);
|
|
|
}
|
|
|
+ if (bindingPathModCount < 5 || (i == 0 && j == 0)) {
|
|
|
+ logger.info("[generateContinuedSheet] pageNo={}, 修改绑定路径: {} -> {}", pageNo, bindingPath, newPath);
|
|
|
+ }
|
|
|
+ bindingPathModCount++;
|
|
|
} catch (NumberFormatException ignored) {
|
|
|
+ logger.warn("[generateContinuedSheet] pageNo={}, 解析数字失败: bindingPath={}", pageNo, bindingPath);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ logger.info("[generateContinuedSheet] pageNo={}, 共修改绑定路径 {} 个", pageNo, bindingPathModCount);
|
|
|
+ logger.info("[generateContinuedSheet] pageNo={}, 完成, afterSheetCount={}", pageNo, workbook.getWorksheets().getCount());
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -736,6 +909,26 @@ public class GrapeCityController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private void fillCellsByBindingPath(IWorksheet worksheet, Map<String, Object> data) {
|
|
|
+ if (worksheet == null || data == null || data.isEmpty()) return;
|
|
|
+
|
|
|
+ int filled = 0;
|
|
|
+ for (int r = 0; r < worksheet.getRowCount(); r++) {
|
|
|
+ for (int c = 0; c < worksheet.getColumnCount(); c++) {
|
|
|
+ IRange range = worksheet.getRange(r, c);
|
|
|
+ String bindingPath = range.getBindingPath();
|
|
|
+ if (bindingPath != null && data.containsKey(bindingPath)) {
|
|
|
+ Object value = data.get(bindingPath);
|
|
|
+ if (!(value instanceof Collection<?>) && !(value instanceof JSONArray)) {
|
|
|
+ range.setValue(value);
|
|
|
+ filled++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ logger.info("[fillCellsByBindingPath] sheet={}, filled={}", worksheet.getName(), filled);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 在 setDataSource 之前收集所有表格第一行数据行的合并单元格规则
|
|
|
*/
|