From 05c3948191f1865bec9d381f4b5d2da4711d2357 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 28 Aug 2019 10:43:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8B=A6=E6=88=AA=E5=99=A8de?= =?UTF-8?q?mo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../quickstart/write/customHandlerWrite.png | Bin 0 -> 4344 bytes quickstart.md | 42 ++++++++++++++-- .../demo/write/CustomCellWriteHandler.java | 45 ++++++++++++++++++ .../demo/write/CustomSheetWriteHandler.java | 39 +++++++++++++++ .../easyexcel/test/demo/write/WriteTest.java | 25 ++++++++-- 5 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 img/readme/quickstart/write/customHandlerWrite.png create mode 100644 src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java create mode 100644 src/test/java/com/alibaba/easyexcel/test/demo/write/CustomSheetWriteHandler.java diff --git a/img/readme/quickstart/write/customHandlerWrite.png b/img/readme/quickstart/write/customHandlerWrite.png new file mode 100644 index 0000000000000000000000000000000000000000..41916c3fb1da3a4f9991d84e26cddfe6629c0219 GIT binary patch literal 4344 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 literal 0 HcmV?d00001 diff --git a/quickstart.md b/quickstart.md index b9a7d0db..6312800c 100644 --- a/quickstart.md +++ b/quickstart.md @@ -24,6 +24,7 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja * [使用table去写入](#tableWrite) * [动态头,实时生成头写入](#dynamicHeadWrite) * [自动列宽(不太精确)](#longestMatchColumnWidthWrite) +* [自定义拦截器(下拉,超链接等上面几点都不符合但是要对单元格进行操作的参照这个)](#customHandlerWrite) * [web中的写](#webWrite) ## 读excel样例 @@ -810,7 +811,7 @@ public class LongestMatchColumnWidthData { ``` ##### 代码 ```java - /** + /** * 自动列宽(不太精确) *

* 这个目前不是很好用,比如有数字就会导致换行。而且长度也不是刚好和实际长度一致。 所以需要精确到刚好列宽的慎用。 当然也可以自己参照 @@ -818,16 +819,20 @@ public class LongestMatchColumnWidthData { *

* poi 自带{@link SXSSFSheet#autoSizeColumn(int)} 对中文支持也不太好。目前没找到很好的算法。 有的话可以推荐下。 * - *

1. 创建excel对应的实体对象 参照{@link DemoData} - *

3. 注册策略{@link LongestMatchColumnWidthStyleStrategy} - *

2. 直接写即可 + *

+ * 1. 创建excel对应的实体对象 参照{@link LongestMatchColumnWidthData} + *

+ * 2. 注册策略{@link LongestMatchColumnWidthStyleStrategy} + *

+ * 3. 直接写即可 */ @Test public void longestMatchColumnWidthWrite() { String fileName = TestFileUtil.getPath() + "longestMatchColumnWidthWrite" + System.currentTimeMillis() + ".xlsx"; // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 - EasyExcel.write(fileName, LongestMatchColumnWidthData.class).sheet("模板").doWrite(dataLong()); + EasyExcel.write(fileName, LongestMatchColumnWidthData.class) + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("模板").doWrite(dataLong()); } private List dataLong() { @@ -843,6 +848,33 @@ public class LongestMatchColumnWidthData { } ``` +### 自定义拦截器(上面几点都不符合但是要对单元格进行操作的参照这个) +##### excel示例 +![img](img/readme/quickstart/write/customHandlerWrite.png) +##### 对象 +参照:[对象](#simpleWriteObject) +##### 代码 +```java + /** + * 下拉,超链接等自定义拦截器(上面几点都不符合但是要对单元格进行操作的参照这个) + *

+ * demo这里实现2点。1. 对第一行第一列的头超链接到:https://github.com/alibaba/easyexcel 2. 对第一列第一行和第二行的数据新增下拉框,显示 测试1 测试2 + *

+ * 1. 创建excel对应的实体对象 参照{@link DemoData} + *

+ * 2. 注册拦截器 {@link CustomCellWriteHandler} {@link CustomSheetWriteHandler} + *

+ * 2. 直接写即可 + */ + @Test + public void customHandlerWrite() { + String fileName = TestFileUtil.getPath() + "customHandlerWrite" + System.currentTimeMillis() + ".xlsx"; + // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + EasyExcel.write(fileName, DemoData.class).registerWriteHandler(new CustomSheetWriteHandler()) + .registerWriteHandler(new CustomCellWriteHandler()).sheet("模板").doWrite(data()); + } +``` + ### web中的写 ##### 示例代码 DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java](/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java) diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java new file mode 100644 index 00000000..bff544a1 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java @@ -0,0 +1,45 @@ +package com.alibaba.easyexcel.test.demo.write; + +import org.apache.poi.common.usermodel.HyperlinkType; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.Hyperlink; +import org.apache.poi.ss.usermodel.Row; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; + +/** + * 自定义拦截器。对第一行第一列的头超链接到:https://github.com/alibaba/easyexcel + * + * @author Jiaju Zhuang + */ +public class CustomCellWriteHandler implements CellWriteHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomCellWriteHandler.class); + + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, + Head head, int relativeRowIndex, boolean isHead) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, + Cell cell, Head head, int relativeRowIndex, boolean isHead) { + // 这里可以对cell进行任何操作 + LOGGER.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex()); + if (isHead && cell.getColumnIndex() == 0) { + CreationHelper createHelper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper(); + Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL); + hyperlink.setAddress("https://github.com/alibaba/easyexcel"); + cell.setHyperlink(hyperlink); + } + } + +} diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomSheetWriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomSheetWriteHandler.java new file mode 100644 index 00000000..fe29045c --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomSheetWriteHandler.java @@ -0,0 +1,39 @@ +package com.alibaba.easyexcel.test.demo.write; + +import org.apache.poi.ss.usermodel.DataValidation; +import org.apache.poi.ss.usermodel.DataValidationConstraint; +import org.apache.poi.ss.usermodel.DataValidationHelper; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.excel.write.handler.SheetWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; + +/** + * 自定义拦截器.对第一列第一行和第二行的数据新增下拉框,显示 测试1 测试2 + * + * @author Jiaju Zhuang + */ +public class CustomSheetWriteHandler implements SheetWriteHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomSheetWriteHandler.class); + + @Override + public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + + } + + @Override + public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + LOGGER.info("第{}个Sheet写入成功。", writeSheetHolder.getSheetNo()); + + // 区间设置 第一列第一行和第二行的数据。由于第一行是头,所以第一、二行的数据实际上是第二三行 + CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 2, 0, 0); + DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper(); + DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[] {"测试1", "测试2"}); + DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList); + writeSheetHolder.getSheet().addValidationData(dataValidation); + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index 482f8f72..e6bc9984 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -311,11 +311,11 @@ public class WriteTest { * poi 自带{@link SXSSFSheet#autoSizeColumn(int)} 对中文支持也不太好。目前没找到很好的算法。 有的话可以推荐下。 * *

- * 1. 创建excel对应的实体对象 参照{@link DemoData} + * 1. 创建excel对应的实体对象 参照{@link LongestMatchColumnWidthData} *

- * 3. 注册策略{@link LongestMatchColumnWidthStyleStrategy} + * 2. 注册策略{@link LongestMatchColumnWidthStyleStrategy} *

- * 2. 直接写即可 + * 3. 直接写即可 */ @Test public void longestMatchColumnWidthWrite() { @@ -326,6 +326,25 @@ public class WriteTest { .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("模板").doWrite(dataLong()); } + /** + * 下拉,超链接等自定义拦截器(上面几点都不符合但是要对单元格进行操作的参照这个) + *

+ * demo这里实现2点。1. 对第一行第一列的头超链接到:https://github.com/alibaba/easyexcel 2. 对第一列第一行和第二行的数据新增下拉框,显示 测试1 测试2 + *

+ * 1. 创建excel对应的实体对象 参照{@link DemoData} + *

+ * 2. 注册拦截器 {@link CustomCellWriteHandler} {@link CustomSheetWriteHandler} + *

+ * 2. 直接写即可 + */ + @Test + public void customHandlerWrite() { + String fileName = TestFileUtil.getPath() + "customHandlerWrite" + System.currentTimeMillis() + ".xlsx"; + // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + EasyExcel.write(fileName, DemoData.class).registerWriteHandler(new CustomSheetWriteHandler()) + .registerWriteHandler(new CustomCellWriteHandler()).sheet("模板").doWrite(data()); + } + private List dataLong() { List list = new ArrayList(); for (int i = 0; i < 10; i++) {