From 92730f28d35300b353acf8eb1ff23edff1a08281 Mon Sep 17 00:00:00 2001 From: liaochong Date: Fri, 15 Dec 2023 17:31:33 +0800 Subject: [PATCH 1/9] support linkage --- .../myexcel/core/AbstractExcelFactory.java | 53 +++++++++++++------ .../core/AbstractSimpleExcelBuilder.java | 13 +++++ .../liaochong/myexcel/core/Configuration.java | 3 ++ .../core/DefaultStreamExcelBuilder.java | 6 +++ .../myexcel/core/ExcelColumnMapping.java | 8 +++ .../liaochong/myexcel/core/ExcelFactory.java | 13 +++++ .../core/HtmlToExcelStreamFactory.java | 17 ++++++ .../myexcel/core/annotation/DropdownList.java | 21 ++++++++ .../myexcel/core/annotation/ExcelColumn.java | 2 + .../myexcel/core/parser/DropdownList.java | 42 +++++++++++++++ .../liaochong/myexcel/core/parser/Td.java | 2 + 11 files changed, 163 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/github/liaochong/myexcel/core/annotation/DropdownList.java create mode 100644 src/main/java/com/github/liaochong/myexcel/core/parser/DropdownList.java diff --git a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java index e6fa5438..eadc5b77 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java @@ -61,6 +61,7 @@ import org.apache.poi.ss.usermodel.ShapeTypes; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.util.CellAddress; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.util.IOUtils; @@ -147,6 +148,10 @@ public abstract class AbstractExcelFactory implements ExcelFactory { * 生成sheet策略,默认生成多个sheet */ protected SheetStrategy sheetStrategy = SheetStrategy.MULTI_SHEET; + + protected Map> nameMapping = Collections.emptyMap(); + + protected Map referMapping = new HashMap<>(); /** * 暂存单元格,由后续行认领 */ @@ -223,6 +228,12 @@ public ExcelFactory sheetStrategy(SheetStrategy sheetStrategy) { return this; } + @Override + public ExcelFactory nameMapping(Map> nameMapping) { + this.nameMapping = nameMapping; + return this; + } + protected String getRealSheetName(String sheetName) { if (sheetName == null) { sheetName = "Sheet"; @@ -289,6 +300,7 @@ protected void createCell(Td td, Sheet sheet, Row currentRow) { cell = currentRow.createCell(td.col, CellType.FORMULA); cell.setCellFormula(td.content); } else { + CellAddress cellAddress; String content = td.content; switch (td.tdContentType) { case DOUBLE: @@ -315,21 +327,33 @@ protected void createCell(Td td, Sheet sheet, Row currentRow) { break; case NUMBER_DROP_DOWN_LIST: cell = currentRow.createCell(td.col, CellType.NUMERIC); - String firstEle = setDropDownList(td, sheet, content); + cellAddress = cell.getAddress(); + if (td.dropdownList != null) { + referMapping.putIfAbsent(td.dropdownList.getName(), cellAddress); + } + String firstEle = setDropDownList(td, sheet, content, cellAddress); if (firstEle != null) { cell.setCellValue(Double.parseDouble(firstEle)); } break; case BOOLEAN_DROP_DOWN_LIST: cell = currentRow.createCell(td.col, CellType.BOOLEAN); - firstEle = setDropDownList(td, sheet, content); + cellAddress = cell.getAddress(); + if (td.dropdownList != null) { + referMapping.putIfAbsent(td.dropdownList.getName(), cellAddress); + } + firstEle = setDropDownList(td, sheet, content, cellAddress); if (firstEle != null) { cell.setCellValue(Boolean.parseBoolean(firstEle)); } break; case DROP_DOWN_LIST: cell = currentRow.createCell(td.col, CellType.STRING); - firstEle = setDropDownList(td, sheet, content); + cellAddress = cell.getAddress(); + if (td.dropdownList != null) { + referMapping.putIfAbsent(td.dropdownList.getName(), cellAddress); + } + firstEle = setDropDownList(td, sheet, content, cellAddress); if (firstEle != null) { cell.setCellValue(firstEle); } @@ -563,25 +587,22 @@ private Cell setLink(Td td, Row currentRow, HyperlinkType hyperlinkType) { return cell; } - private String setDropDownList(Td td, Sheet sheet, String content) { + private String setDropDownList(Td td, Sheet sheet, String content, CellAddress cellAddress) { if (content != null && !content.isEmpty()) { CellRangeAddressList addressList = new CellRangeAddressList( td.row, td.getRowBound(), td.col, td.getColBound()); DataValidationHelper dvHelper = sheet.getDataValidationHelper(); - String[] list; + DropDownLists.Index index = DropDownLists.getHiddenSheetIndex(content, workbook); + String[] list = new String[]{index.firstLine}; DataValidation validation; - if (content.length() <= 250) { - list = content.split(","); - DataValidationConstraint dvConstraint = dvHelper.createExplicitListConstraint(list); - validation = dvHelper.createValidation( - dvConstraint, addressList); - + boolean linkage = td.dropdownList != null && StringUtil.isNotBlank(td.dropdownList.getParent()); + if (linkage) { + CellAddress parentCellAddress = referMapping.get(td.dropdownList.getParent()); + String refer = new CellAddress(cellAddress.getRow(), parentCellAddress.getColumn()).formatAsString(); + validation = dvHelper.createValidation(dvHelper.createFormulaListConstraint("=INDIRECT($" + refer + ")"), addressList); } else { - DropDownLists.Index index = DropDownLists.getHiddenSheetIndex(content, workbook); - list = new String[]{index.firstLine}; validation = dvHelper.createValidation(dvHelper.createFormulaListConstraint(index.path), addressList); } - if (td.promptContainer != null) { validation.createPromptBox(td.promptContainer.title, td.promptContainer.text); validation.setShowPromptBox(true); @@ -593,9 +614,7 @@ private String setDropDownList(Td td, Sheet sheet, String content) { validation.setSuppressDropDownArrow(false); } sheet.addValidationData(validation); - if (list.length > 0) { - return list[0]; - } + return linkage ? null : list[0]; } return null; } diff --git a/src/main/java/com/github/liaochong/myexcel/core/AbstractSimpleExcelBuilder.java b/src/main/java/com/github/liaochong/myexcel/core/AbstractSimpleExcelBuilder.java index cec5a441..9d1a82b7 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/AbstractSimpleExcelBuilder.java +++ b/src/main/java/com/github/liaochong/myexcel/core/AbstractSimpleExcelBuilder.java @@ -240,6 +240,7 @@ protected List createThead() { td.content = multiTitles[j]; this.setPrompt(td, i); this.setImage(td, i); + this.setDropdownList(td, i); tds.add(td); } tdLists.add(tds); @@ -342,6 +343,7 @@ protected Tr createTr(List> contents) { this.setFormula(index, td); this.setPrompt(td, index); this.setImage(td, index); + this.setDropdownList(td, index); } this.setTdWidth(tr.colWidthMap, td); return td; @@ -399,6 +401,17 @@ protected void setImage(Td td, int index) { } } + protected void setDropdownList(Td td, int index) { + if (filteredFields.isEmpty()) { + return; + } + FieldDefinition fieldDefinition = filteredFields.get(index); + ExcelColumnMapping excelColumnMapping = excelColumnMappingMap.get(fieldDefinition.getField()); + if (excelColumnMapping != null && excelColumnMapping.dropdownList != null) { + td.dropdownList = excelColumnMapping.dropdownList; + } + } + private void setTdContent(Td td, Pair pair) { Class fieldType = pair.getKey(); if (fieldType == NullType.class) { diff --git a/src/main/java/com/github/liaochong/myexcel/core/Configuration.java b/src/main/java/com/github/liaochong/myexcel/core/Configuration.java index 9ad815e7..7f789714 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/Configuration.java +++ b/src/main/java/com/github/liaochong/myexcel/core/Configuration.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -107,6 +108,8 @@ public class Configuration { */ public Map, Object> applicationBeans = Collections.emptyMap(); + public Map> nameMapping = Collections.emptyMap(); + public void setWidthStrategy(WidthStrategy widthStrategy) { this.widthStrategy = widthStrategy; this.computeAutoWidth = WidthStrategy.isComputeAutoWidth(widthStrategy); diff --git a/src/main/java/com/github/liaochong/myexcel/core/DefaultStreamExcelBuilder.java b/src/main/java/com/github/liaochong/myexcel/core/DefaultStreamExcelBuilder.java index d9b0985b..940e8b93 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/DefaultStreamExcelBuilder.java +++ b/src/main/java/com/github/liaochong/myexcel/core/DefaultStreamExcelBuilder.java @@ -304,6 +304,11 @@ public DefaultStreamExcelBuilder autoMerge() { return this; } + public DefaultStreamExcelBuilder nameManager(Map> nameMapping) { + this.configuration.nameMapping = nameMapping; + return this; + } + /** * 流式构建启动,包含一些初始化操作 * @@ -320,6 +325,7 @@ public DefaultStreamExcelBuilder start() { context.styleParser = styleParser; htmlToExcelStreamFactory = new HtmlToExcelStreamFactory(context); htmlToExcelStreamFactory.widthStrategy(configuration.widthStrategy); + htmlToExcelStreamFactory.nameMapping(configuration.nameMapping); if (workbook == null) { htmlToExcelStreamFactory.workbookType(configuration.workbookType); } diff --git a/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java b/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java index 424fac7b..31a6527f 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java +++ b/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java @@ -19,6 +19,7 @@ import com.github.liaochong.myexcel.core.constant.FileType; import com.github.liaochong.myexcel.core.constant.LinkType; import com.github.liaochong.myexcel.core.converter.CustomWriteConverter; +import com.github.liaochong.myexcel.core.parser.DropdownList; import com.github.liaochong.myexcel.core.parser.Image; import com.github.liaochong.myexcel.utils.StringUtil; @@ -104,6 +105,8 @@ public final class ExcelColumnMapping { public Image image; + public DropdownList dropdownList; + public static ExcelColumnMapping mapping(ExcelColumn excelColumn) { ExcelColumnMapping result = new ExcelColumnMapping(); result.title = excelColumn.title(); @@ -154,6 +157,11 @@ public static ExcelColumnMapping mapping(ExcelColumn excelColumn) { if (image.height() > 0) { result.image.setHeight(image.height()); } + com.github.liaochong.myexcel.core.annotation.DropdownList dr = excelColumn.dropdownList(); + DropdownList drList = new DropdownList(); + drList.setName(dr.name()); + drList.setParent(dr.parent()); + result.dropdownList = drList; return result; } } diff --git a/src/main/java/com/github/liaochong/myexcel/core/ExcelFactory.java b/src/main/java/com/github/liaochong/myexcel/core/ExcelFactory.java index 25ae303b..1ee33802 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/ExcelFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/ExcelFactory.java @@ -19,6 +19,9 @@ import com.github.liaochong.myexcel.core.strategy.WidthStrategy; import org.apache.poi.ss.usermodel.Workbook; +import java.util.List; +import java.util.Map; + /** * @author liaochong * @version 1.0 @@ -71,6 +74,16 @@ public interface ExcelFactory { */ ExcelFactory sheetStrategy(SheetStrategy sheetStrategy); + /** + * 指定名称管理器 + * + * @param nameMapping 名称映射 + * @return ExcelFactory + */ + default ExcelFactory nameMapping(Map> nameMapping) { + return this; + } + /** * 构建 * diff --git a/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java b/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java index 625f35aa..1f1e7af0 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java @@ -16,6 +16,7 @@ package com.github.liaochong.myexcel.core; import com.github.liaochong.myexcel.core.constant.Constants; +import com.github.liaochong.myexcel.core.parser.DropDownLists; import com.github.liaochong.myexcel.core.parser.StyleParser; import com.github.liaochong.myexcel.core.parser.Table; import com.github.liaochong.myexcel.core.parser.Td; @@ -25,6 +26,7 @@ import com.github.liaochong.myexcel.utils.StringUtil; import com.github.liaochong.myexcel.utils.TdUtil; import com.github.liaochong.myexcel.utils.TempFileOperator; +import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.PrintSetup; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; @@ -150,6 +152,8 @@ private void receive() { if (this.workbook == null) { workbookType(WorkbookType.SXLSX); } + // 构建名称管理器 + this.createNameManager(); if (isHssf) { maxRowCountOfSheet = XLS_MAX_ROW_COUNT; } @@ -209,6 +213,19 @@ private void receive() { } } + private void createNameManager() { + if (nameMapping.isEmpty()) { + return; + } + for (Map.Entry> entry : nameMapping.entrySet()) { + Name name = workbook.createName(); + name.setNameName(entry.getKey()); + String content = entry.getValue().stream().map(String::valueOf).collect(Collectors.joining(Constants.COMMA)); + DropDownLists.Index index = DropDownLists.getHiddenSheetIndex(content, workbook); + name.setRefersToFormula(index.path); + } + } + private void createNextSheet() { if (rowNum >= maxRowCountOfSheet) { sheetNum++; diff --git a/src/main/java/com/github/liaochong/myexcel/core/annotation/DropdownList.java b/src/main/java/com/github/liaochong/myexcel/core/annotation/DropdownList.java new file mode 100644 index 00000000..517f414e --- /dev/null +++ b/src/main/java/com/github/liaochong/myexcel/core/annotation/DropdownList.java @@ -0,0 +1,21 @@ +package com.github.liaochong.myexcel.core.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author liaochong + * @version 1.0 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +@Documented +public @interface DropdownList { + + String name() default ""; + + String parent() default ""; +} diff --git a/src/main/java/com/github/liaochong/myexcel/core/annotation/ExcelColumn.java b/src/main/java/com/github/liaochong/myexcel/core/annotation/ExcelColumn.java index 3995a52a..988bf804 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/annotation/ExcelColumn.java +++ b/src/main/java/com/github/liaochong/myexcel/core/annotation/ExcelColumn.java @@ -163,4 +163,6 @@ * @return 图片配置 */ Image image() default @Image(); + + DropdownList dropdownList() default @DropdownList; } diff --git a/src/main/java/com/github/liaochong/myexcel/core/parser/DropdownList.java b/src/main/java/com/github/liaochong/myexcel/core/parser/DropdownList.java new file mode 100644 index 00000000..c3479b75 --- /dev/null +++ b/src/main/java/com/github/liaochong/myexcel/core/parser/DropdownList.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019 liaochong + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.github.liaochong.myexcel.core.parser; + +/** + * @author liaochong + * @version 1.0 + */ +public class DropdownList { + + private String name; + + private String parent; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } +} diff --git a/src/main/java/com/github/liaochong/myexcel/core/parser/Td.java b/src/main/java/com/github/liaochong/myexcel/core/parser/Td.java index af7c4b46..2a4355ce 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/parser/Td.java +++ b/src/main/java/com/github/liaochong/myexcel/core/parser/Td.java @@ -108,6 +108,8 @@ public class Td { public Image image; + public DropdownList dropdownList; + public Td(int row, int col) { this.row = row; this.col = col; From 143123c53feb61e3b24f1c103afdb7e551579101 Mon Sep 17 00:00:00 2001 From: liaochong Date: Sat, 16 Dec 2023 10:08:19 +0800 Subject: [PATCH 2/9] fix bug --- .../liaochong/myexcel/core/HtmlToExcelStreamFactory.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java b/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java index 1f1e7af0..19141ebf 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java @@ -152,8 +152,6 @@ private void receive() { if (this.workbook == null) { workbookType(WorkbookType.SXLSX); } - // 构建名称管理器 - this.createNameManager(); if (isHssf) { maxRowCountOfSheet = XLS_MAX_ROW_COUNT; } @@ -181,6 +179,8 @@ private void receive() { } sheet.setColumnWidth(key, contentLength << 8); }); + // 构建名称管理器 + this.createNameManager(); int totalSize = 0; while (tr != STOP_FLAG) { if (context.capacity > 0 && count == context.capacity) { From 3fcba5b8c4ee9219d9e2302365728a90f12a9a84 Mon Sep 17 00:00:00 2001 From: liaochong Date: Sat, 16 Dec 2023 17:59:17 +0800 Subject: [PATCH 3/9] optimize --- .../liaochong/myexcel/core/ExcelColumnMapping.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java b/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java index 31a6527f..9b3e5791 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java +++ b/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java @@ -158,10 +158,12 @@ public static ExcelColumnMapping mapping(ExcelColumn excelColumn) { result.image.setHeight(image.height()); } com.github.liaochong.myexcel.core.annotation.DropdownList dr = excelColumn.dropdownList(); - DropdownList drList = new DropdownList(); - drList.setName(dr.name()); - drList.setParent(dr.parent()); - result.dropdownList = drList; + if (StringUtil.isNotBlank(dr.name()) || StringUtil.isNotBlank(dr.parent())) { + DropdownList drList = new DropdownList(); + drList.setName(dr.name()); + drList.setParent(dr.parent()); + result.dropdownList = drList; + } return result; } } From 50e0c5e4eab4cdaa43b98cf1b556491dabfb8ad1 Mon Sep 17 00:00:00 2001 From: liaochong Date: Sat, 23 Dec 2023 15:12:13 +0800 Subject: [PATCH 4/9] optimize --- pom.xml | 2 +- .../myexcel/core/AbstractExcelFactory.java | 35 +++++++++--------- .../core/AbstractSimpleExcelBuilder.java | 36 ++++++++++--------- .../liaochong/myexcel/core/Configuration.java | 4 ++- .../myexcel/core/annotation/ExcelColumn.java | 5 +++ .../myexcel/core/parser/DropdownList.java | 2 ++ .../liaochong/myexcel/core/parser/Td.java | 8 +++-- 7 files changed, 54 insertions(+), 38 deletions(-) diff --git a/pom.xml b/pom.xml index 7bf7f46b..5d7240cb 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ com.github.liaochong myexcel - 4.4.2 + 4.5.0 jar myexcel diff --git a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java index eadc5b77..29c691e0 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java @@ -148,9 +148,13 @@ public abstract class AbstractExcelFactory implements ExcelFactory { * 生成sheet策略,默认生成多个sheet */ protected SheetStrategy sheetStrategy = SheetStrategy.MULTI_SHEET; - + /** + * 用于保存名称管理 + */ protected Map> nameMapping = Collections.emptyMap(); - + /** + * 用于保存下拉列表所需引用 + */ protected Map referMapping = new HashMap<>(); /** * 暂存单元格,由后续行认领 @@ -300,7 +304,6 @@ protected void createCell(Td td, Sheet sheet, Row currentRow) { cell = currentRow.createCell(td.col, CellType.FORMULA); cell.setCellFormula(td.content); } else { - CellAddress cellAddress; String content = td.content; switch (td.tdContentType) { case DOUBLE: @@ -327,33 +330,21 @@ protected void createCell(Td td, Sheet sheet, Row currentRow) { break; case NUMBER_DROP_DOWN_LIST: cell = currentRow.createCell(td.col, CellType.NUMERIC); - cellAddress = cell.getAddress(); - if (td.dropdownList != null) { - referMapping.putIfAbsent(td.dropdownList.getName(), cellAddress); - } - String firstEle = setDropDownList(td, sheet, content, cellAddress); + String firstEle = this.process(td, sheet, cell, content); if (firstEle != null) { cell.setCellValue(Double.parseDouble(firstEle)); } break; case BOOLEAN_DROP_DOWN_LIST: cell = currentRow.createCell(td.col, CellType.BOOLEAN); - cellAddress = cell.getAddress(); - if (td.dropdownList != null) { - referMapping.putIfAbsent(td.dropdownList.getName(), cellAddress); - } - firstEle = setDropDownList(td, sheet, content, cellAddress); + firstEle = this.process(td, sheet, cell, content); if (firstEle != null) { cell.setCellValue(Boolean.parseBoolean(firstEle)); } break; case DROP_DOWN_LIST: cell = currentRow.createCell(td.col, CellType.STRING); - cellAddress = cell.getAddress(); - if (td.dropdownList != null) { - referMapping.putIfAbsent(td.dropdownList.getName(), cellAddress); - } - firstEle = setDropDownList(td, sheet, content, cellAddress); + firstEle = this.process(td, sheet, cell, content); if (firstEle != null) { cell.setCellValue(firstEle); } @@ -392,6 +383,14 @@ protected void createCell(Td td, Sheet sheet, Row currentRow) { } } + private String process(Td td, Sheet sheet, Cell cell, String content) { + CellAddress cellAddress = cell.getAddress(); + if (td.dropdownList != null) { + referMapping.putIfAbsent(td.dropdownList.getName(), cellAddress); + } + return this.setDropDownList(td, sheet, content, cellAddress); + } + private void setComment(Td td, Sheet sheet, Cell cell) { if (td.comment == null) { return; diff --git a/src/main/java/com/github/liaochong/myexcel/core/AbstractSimpleExcelBuilder.java b/src/main/java/com/github/liaochong/myexcel/core/AbstractSimpleExcelBuilder.java index 9d1a82b7..10d96544 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/AbstractSimpleExcelBuilder.java +++ b/src/main/java/com/github/liaochong/myexcel/core/AbstractSimpleExcelBuilder.java @@ -369,49 +369,53 @@ private void setTdWidth(Map colWidthMap, Td td) { } private void setFormula(int i, Td td) { - if (filteredFields.isEmpty()) { + ExcelColumnMapping excelColumnMapping = getExcelColumnMapping(i); + if (excelColumnMapping == null) { return; } - FieldDefinition fieldDefinition = filteredFields.get(i); - ExcelColumnMapping excelColumnMapping = excelColumnMappingMap.get(fieldDefinition.getField()); - if (excelColumnMapping != null && excelColumnMapping.formula) { + if (excelColumnMapping.formula) { td.formula = true; } } protected void setPrompt(Td td, int index) { - if (filteredFields.isEmpty()) { + ExcelColumnMapping excelColumnMapping = getExcelColumnMapping(index); + if (excelColumnMapping == null) { return; } - FieldDefinition fieldDefinition = filteredFields.get(index); - ExcelColumnMapping excelColumnMapping = excelColumnMappingMap.get(fieldDefinition.getField()); - if (excelColumnMapping != null && excelColumnMapping.promptContainer != null) { + if (excelColumnMapping.promptContainer != null) { td.promptContainer = excelColumnMapping.promptContainer; } } protected void setImage(Td td, int index) { - if (filteredFields.isEmpty()) { + ExcelColumnMapping excelColumnMapping = getExcelColumnMapping(index); + if (excelColumnMapping == null) { return; } - FieldDefinition fieldDefinition = filteredFields.get(index); - ExcelColumnMapping excelColumnMapping = excelColumnMappingMap.get(fieldDefinition.getField()); - if (excelColumnMapping != null && excelColumnMapping.image != null) { + if (excelColumnMapping.image != null) { td.image = excelColumnMapping.image; } } protected void setDropdownList(Td td, int index) { - if (filteredFields.isEmpty()) { + ExcelColumnMapping excelColumnMapping = getExcelColumnMapping(index); + if (excelColumnMapping == null) { return; } - FieldDefinition fieldDefinition = filteredFields.get(index); - ExcelColumnMapping excelColumnMapping = excelColumnMappingMap.get(fieldDefinition.getField()); - if (excelColumnMapping != null && excelColumnMapping.dropdownList != null) { + if (excelColumnMapping.dropdownList != null) { td.dropdownList = excelColumnMapping.dropdownList; } } + private ExcelColumnMapping getExcelColumnMapping(int index) { + if (filteredFields.isEmpty()) { + return null; + } + FieldDefinition fieldDefinition = filteredFields.get(index); + return excelColumnMappingMap.get(fieldDefinition.getField()); + } + private void setTdContent(Td td, Pair pair) { Class fieldType = pair.getKey(); if (fieldType == NullType.class) { diff --git a/src/main/java/com/github/liaochong/myexcel/core/Configuration.java b/src/main/java/com/github/liaochong/myexcel/core/Configuration.java index 7f789714..e1a0fef1 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/Configuration.java +++ b/src/main/java/com/github/liaochong/myexcel/core/Configuration.java @@ -107,7 +107,9 @@ public class Configuration { * 绑定的上下文,适用spring等容器环境 */ public Map, Object> applicationBeans = Collections.emptyMap(); - + /** + * 名称管理映射 + */ public Map> nameMapping = Collections.emptyMap(); public void setWidthStrategy(WidthStrategy widthStrategy) { diff --git a/src/main/java/com/github/liaochong/myexcel/core/annotation/ExcelColumn.java b/src/main/java/com/github/liaochong/myexcel/core/annotation/ExcelColumn.java index 988bf804..6f60dbfe 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/annotation/ExcelColumn.java +++ b/src/main/java/com/github/liaochong/myexcel/core/annotation/ExcelColumn.java @@ -164,5 +164,10 @@ */ Image image() default @Image(); + /** + * 下拉列表配置 + * + * @return 下拉列表配置 + */ DropdownList dropdownList() default @DropdownList; } diff --git a/src/main/java/com/github/liaochong/myexcel/core/parser/DropdownList.java b/src/main/java/com/github/liaochong/myexcel/core/parser/DropdownList.java index c3479b75..9552aab4 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/parser/DropdownList.java +++ b/src/main/java/com/github/liaochong/myexcel/core/parser/DropdownList.java @@ -15,6 +15,8 @@ package com.github.liaochong.myexcel.core.parser; /** + * 下拉列表配置 + * * @author liaochong * @version 1.0 */ diff --git a/src/main/java/com/github/liaochong/myexcel/core/parser/Td.java b/src/main/java/com/github/liaochong/myexcel/core/parser/Td.java index 2a4355ce..02fc0d70 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/parser/Td.java +++ b/src/main/java/com/github/liaochong/myexcel/core/parser/Td.java @@ -105,9 +105,13 @@ public class Td { * 批注 */ public Comment comment; - + /** + * 图片配置 + */ public Image image; - + /** + * 下拉列表配置 + */ public DropdownList dropdownList; public Td(int row, int col) { From ceedf3c50e0d944709fa1b7fa5170b2f1bc1de45 Mon Sep 17 00:00:00 2001 From: liaochong Date: Sat, 23 Dec 2023 15:40:00 +0800 Subject: [PATCH 5/9] optimize --- .../myexcel/core/AbstractExcelBuilder.java | 7 +++++++ .../myexcel/core/AbstractExcelFactory.java | 17 +++++++++++++++++ .../liaochong/myexcel/core/ExcelBuilder.java | 11 +++++++++++ .../myexcel/core/HtmlToExcelFactory.java | 2 ++ .../myexcel/core/HtmlToExcelStreamFactory.java | 15 --------------- .../myexcel/core/parser/HtmlTableParser.java | 15 ++++++++++++++- 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java index 9b2b9469..7105f1d8 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java +++ b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java @@ -24,6 +24,7 @@ import org.apache.poi.ss.usermodel.Workbook; import java.io.IOException; +import java.util.List; import java.util.Map; /** @@ -90,6 +91,12 @@ public AbstractExcelBuilder freezePanes(FreezePane... freezePanes) { return this; } + @Override + public ExcelBuilder nameMapping(Map> nameMapping) { + htmlToExcelFactory.nameMapping(nameMapping); + return this; + } + /** * 构建 * diff --git a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java index 29c691e0..db844d2f 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java @@ -15,6 +15,7 @@ */ package com.github.liaochong.myexcel.core; +import com.github.liaochong.myexcel.core.constant.Constants; import com.github.liaochong.myexcel.core.parser.ContentTypeEnum; import com.github.liaochong.myexcel.core.parser.DropDownLists; import com.github.liaochong.myexcel.core.parser.HtmlTableParser; @@ -55,6 +56,7 @@ import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Hyperlink; +import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.Picture; import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.Row; @@ -88,6 +90,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; /** * @author liaochong @@ -238,6 +241,20 @@ public ExcelFactory nameMapping(Map> nameMapping) { return this; } + protected void createNameManager() { + if (nameMapping.isEmpty()) { + return; + } + for (Map.Entry> entry : nameMapping.entrySet()) { + Name name = workbook.createName(); + name.setNameName(entry.getKey()); + String content = entry.getValue().stream().map(String::valueOf).collect(Collectors.joining(Constants.COMMA)); + DropDownLists.Index index = DropDownLists.getHiddenSheetIndex(content, workbook); + name.setRefersToFormula(index.path); + } + } + + protected String getRealSheetName(String sheetName) { if (sheetName == null) { sheetName = "Sheet"; diff --git a/src/main/java/com/github/liaochong/myexcel/core/ExcelBuilder.java b/src/main/java/com/github/liaochong/myexcel/core/ExcelBuilder.java index 2c70780b..1524d9c1 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/ExcelBuilder.java +++ b/src/main/java/com/github/liaochong/myexcel/core/ExcelBuilder.java @@ -21,6 +21,7 @@ import org.apache.poi.ss.usermodel.Workbook; import java.io.Closeable; +import java.util.List; import java.util.Map; /** @@ -112,6 +113,16 @@ public interface ExcelBuilder extends Closeable { */ ExcelBuilder fileTemplate(String dirPath, String fileName); + /** + * 指定名称管理器 + * + * @param nameMapping 名称映射 + * @return ExcelFactory + */ + default ExcelBuilder nameMapping(Map> nameMapping) { + return this; + } + /** * 构建 * diff --git a/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelFactory.java b/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelFactory.java index 49a38b87..0b7f8a6e 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelFactory.java @@ -170,6 +170,8 @@ Workbook build(List tables) { } else { buildTablesWithOneSheet(tables); } + // 3.创建名称管理 + this.createNameManager(); log.info("Build excel takes {} ms", System.currentTimeMillis() - startTime); return workbook; } diff --git a/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java b/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java index 19141ebf..22ff100f 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/HtmlToExcelStreamFactory.java @@ -16,7 +16,6 @@ package com.github.liaochong.myexcel.core; import com.github.liaochong.myexcel.core.constant.Constants; -import com.github.liaochong.myexcel.core.parser.DropDownLists; import com.github.liaochong.myexcel.core.parser.StyleParser; import com.github.liaochong.myexcel.core.parser.Table; import com.github.liaochong.myexcel.core.parser.Td; @@ -26,7 +25,6 @@ import com.github.liaochong.myexcel.utils.StringUtil; import com.github.liaochong.myexcel.utils.TdUtil; import com.github.liaochong.myexcel.utils.TempFileOperator; -import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.PrintSetup; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; @@ -213,19 +211,6 @@ private void receive() { } } - private void createNameManager() { - if (nameMapping.isEmpty()) { - return; - } - for (Map.Entry> entry : nameMapping.entrySet()) { - Name name = workbook.createName(); - name.setNameName(entry.getKey()); - String content = entry.getValue().stream().map(String::valueOf).collect(Collectors.joining(Constants.COMMA)); - DropDownLists.Index index = DropDownLists.getHiddenSheetIndex(content, workbook); - name.setRefersToFormula(index.path); - } - } - private void createNextSheet() { if (rowNum >= maxRowCountOfSheet) { sheetNum++; diff --git a/src/main/java/com/github/liaochong/myexcel/core/parser/HtmlTableParser.java b/src/main/java/com/github/liaochong/myexcel/core/parser/HtmlTableParser.java index f9c9058a..b24fc1f6 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/parser/HtmlTableParser.java +++ b/src/main/java/com/github/liaochong/myexcel/core/parser/HtmlTableParser.java @@ -385,8 +385,21 @@ private void setTdContent(Element tdElement, Td td) { td.link = link; return; } - if (tdElement.hasAttr("dropDownList")) { + if (tdElement.hasAttr("dropdownList") || tdElement.hasAttr("dropDownList")) { td.tdContentType = ContentTypeEnum.DROP_DOWN_LIST; + String dropdownListName = tdElement.attr("dropdownList-name"); + if (StringUtil.isNotBlank(dropdownListName)) { + DropdownList dropdownList = new DropdownList(); + dropdownList.setName(dropdownListName); + td.dropdownList = dropdownList; + } + String dropdownListParent = tdElement.attr("dropdownList-parent"); + if (StringUtil.isNotBlank(dropdownListParent)) { + if (td.dropdownList == null) { + td.dropdownList = new DropdownList(); + } + td.dropdownList.setParent(dropdownListParent); + } return; } if (Constants.TRUE.equals(content) || Constants.FALSE.equals(content)) { From 19d296a2f6ae51af0051a26d7ef3e3a2a114901d Mon Sep 17 00:00:00 2001 From: liaochong Date: Sat, 23 Dec 2023 15:45:08 +0800 Subject: [PATCH 6/9] optimize --- .../myexcel/core/AbstractExcelFactory.java | 3 +++ .../liaochong/myexcel/core/ExcelColumnMapping.java | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java index db844d2f..8d8dc9ba 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java @@ -565,6 +565,9 @@ private void setImage(Td td, Sheet sheet) { ClientAnchor anchor = createHelper.createClientAnchor(); anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE); Image image = td.getImage(); + if (image == null) { + image = new Image(); + } anchor.setDx1(isHssf ? (image.getMarginLeft() > 0 ? image.getMarginLeft() : 2) : Units.pixelToEMU(image.getMarginLeft() > 0 ? image.getMarginLeft() : 3)); anchor.setDy1(isHssf ? (image.getMarginTop() > 0 ? image.getMarginTop() : 1) : Units.pixelToEMU(image.getMarginTop() > 0 ? image.getMarginTop() : 3)); anchor.setCol1(td.col); diff --git a/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java b/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java index 9b3e5791..572aac53 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java +++ b/src/main/java/com/github/liaochong/myexcel/core/ExcelColumnMapping.java @@ -140,21 +140,33 @@ public static ExcelColumnMapping mapping(ExcelColumn excelColumn) { result.promptContainer = promptContainer; } com.github.liaochong.myexcel.core.annotation.Image image = excelColumn.image(); - result.image = new Image(); if (image.scaleX() > 0 && image.scaleY() > 0) { result.image.setScaleX(image.scaleX()); result.image.setScaleY(image.scaleY()); + result.image = new Image(); } if ((image.marginTop() > 0)) { + if (result.image == null) { + result.image = new Image(); + } result.image.setMarginTop(image.marginTop()); } if ((image.marginLeft() > 0)) { + if (result.image == null) { + result.image = new Image(); + } result.image.setMarginLeft(image.marginLeft()); } if (image.width() > 0) { + if (result.image == null) { + result.image = new Image(); + } result.image.setWidth(image.width()); } if (image.height() > 0) { + if (result.image == null) { + result.image = new Image(); + } result.image.setHeight(image.height()); } com.github.liaochong.myexcel.core.annotation.DropdownList dr = excelColumn.dropdownList(); From f405afe243c824aa89bdd0f6e6352501a97ade2f Mon Sep 17 00:00:00 2001 From: liaochong Date: Sat, 23 Dec 2023 16:00:56 +0800 Subject: [PATCH 7/9] optimize --- .../com/github/liaochong/myexcel/core/AbstractExcelBuilder.java | 2 +- .../java/com/github/liaochong/myexcel/core/ExcelBuilder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java index 7105f1d8..b0b8423b 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java +++ b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java @@ -92,7 +92,7 @@ public AbstractExcelBuilder freezePanes(FreezePane... freezePanes) { } @Override - public ExcelBuilder nameMapping(Map> nameMapping) { + public ExcelBuilder nameManager(Map> nameMapping) { htmlToExcelFactory.nameMapping(nameMapping); return this; } diff --git a/src/main/java/com/github/liaochong/myexcel/core/ExcelBuilder.java b/src/main/java/com/github/liaochong/myexcel/core/ExcelBuilder.java index 1524d9c1..10248d74 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/ExcelBuilder.java +++ b/src/main/java/com/github/liaochong/myexcel/core/ExcelBuilder.java @@ -119,7 +119,7 @@ public interface ExcelBuilder extends Closeable { * @param nameMapping 名称映射 * @return ExcelFactory */ - default ExcelBuilder nameMapping(Map> nameMapping) { + default ExcelBuilder nameManager(Map> nameMapping) { return this; } From 201c503d89de877daccf5559e056f7d932c33679 Mon Sep 17 00:00:00 2001 From: liaochong Date: Sat, 23 Dec 2023 16:06:50 +0800 Subject: [PATCH 8/9] optimize --- .../liaochong/myexcel/core/parser/HtmlTableParser.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/liaochong/myexcel/core/parser/HtmlTableParser.java b/src/main/java/com/github/liaochong/myexcel/core/parser/HtmlTableParser.java index b24fc1f6..d2c522b5 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/parser/HtmlTableParser.java +++ b/src/main/java/com/github/liaochong/myexcel/core/parser/HtmlTableParser.java @@ -385,15 +385,15 @@ private void setTdContent(Element tdElement, Td td) { td.link = link; return; } - if (tdElement.hasAttr("dropdownList") || tdElement.hasAttr("dropDownList")) { + if (tdElement.hasAttr("dropdownlist") || tdElement.hasAttr("dropDownList")) { td.tdContentType = ContentTypeEnum.DROP_DOWN_LIST; - String dropdownListName = tdElement.attr("dropdownList-name"); + String dropdownListName = tdElement.attr("dropdownlist-name"); if (StringUtil.isNotBlank(dropdownListName)) { DropdownList dropdownList = new DropdownList(); dropdownList.setName(dropdownListName); td.dropdownList = dropdownList; } - String dropdownListParent = tdElement.attr("dropdownList-parent"); + String dropdownListParent = tdElement.attr("dropdownlist-parent"); if (StringUtil.isNotBlank(dropdownListParent)) { if (td.dropdownList == null) { td.dropdownList = new DropdownList(); From e7eb47a28138c89ec49be5109d71e34542179738 Mon Sep 17 00:00:00 2001 From: liaochong Date: Fri, 29 Dec 2023 14:00:07 +0800 Subject: [PATCH 9/9] optimize --- .../com/github/liaochong/myexcel/core/AbstractExcelBuilder.java | 2 +- .../com/github/liaochong/myexcel/core/AbstractExcelFactory.java | 2 +- .../liaochong/myexcel/core/DefaultStreamExcelBuilder.java | 2 +- .../java/com/github/liaochong/myexcel/core/ExcelFactory.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java index b0b8423b..50dd5be1 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java +++ b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelBuilder.java @@ -93,7 +93,7 @@ public AbstractExcelBuilder freezePanes(FreezePane... freezePanes) { @Override public ExcelBuilder nameManager(Map> nameMapping) { - htmlToExcelFactory.nameMapping(nameMapping); + htmlToExcelFactory.nameManager(nameMapping); return this; } diff --git a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java index 8d8dc9ba..ae262019 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/AbstractExcelFactory.java @@ -236,7 +236,7 @@ public ExcelFactory sheetStrategy(SheetStrategy sheetStrategy) { } @Override - public ExcelFactory nameMapping(Map> nameMapping) { + public ExcelFactory nameManager(Map> nameMapping) { this.nameMapping = nameMapping; return this; } diff --git a/src/main/java/com/github/liaochong/myexcel/core/DefaultStreamExcelBuilder.java b/src/main/java/com/github/liaochong/myexcel/core/DefaultStreamExcelBuilder.java index 940e8b93..d9a07596 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/DefaultStreamExcelBuilder.java +++ b/src/main/java/com/github/liaochong/myexcel/core/DefaultStreamExcelBuilder.java @@ -325,7 +325,7 @@ public DefaultStreamExcelBuilder start() { context.styleParser = styleParser; htmlToExcelStreamFactory = new HtmlToExcelStreamFactory(context); htmlToExcelStreamFactory.widthStrategy(configuration.widthStrategy); - htmlToExcelStreamFactory.nameMapping(configuration.nameMapping); + htmlToExcelStreamFactory.nameManager(configuration.nameMapping); if (workbook == null) { htmlToExcelStreamFactory.workbookType(configuration.workbookType); } diff --git a/src/main/java/com/github/liaochong/myexcel/core/ExcelFactory.java b/src/main/java/com/github/liaochong/myexcel/core/ExcelFactory.java index 1ee33802..53196353 100644 --- a/src/main/java/com/github/liaochong/myexcel/core/ExcelFactory.java +++ b/src/main/java/com/github/liaochong/myexcel/core/ExcelFactory.java @@ -80,7 +80,7 @@ public interface ExcelFactory { * @param nameMapping 名称映射 * @return ExcelFactory */ - default ExcelFactory nameMapping(Map> nameMapping) { + default ExcelFactory nameManager(Map> nameMapping) { return this; }