From b90988e1949d7f309e2dbbf842220274628943c4 Mon Sep 17 00:00:00 2001 From: zhuangjiaju Date: Thu, 8 Aug 2019 11:15:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=BB=E5=86=99=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../quickstart/write/dynamicHeadWrite.png | Bin 0 -> 4649 bytes quickstart.md | 42 +++++++++++ .../annotation/write/style/ColumnWidth.java | 3 +- .../excel/context/WriteContextImpl.java | 2 +- .../excel/metadata/AbstractHolder.java | 4 +- .../alibaba/excel/write/ExcelBuilderImpl.java | 28 ++++---- .../excel/write/handler/CellWriteHandler.java | 7 +- .../write/merge/AbstractMergeStrategy.java | 5 +- .../style/AbstractCellStyleStrategy.java | 5 +- .../AbstractColumnWidthStyleStrategy.java | 14 ++-- .../AbstractHeadColumnWidthStyleStrategy.java | 8 ++- .../LongestMatchColumnWidthStyleStrategy.java | 66 ++++++++++++++++++ .../write/LongestMatchColumnWidthData.java | 22 ++++++ .../easyexcel/test/demo/write/WriteTest.java | 65 +++++++++++++++++ 14 files changed, 238 insertions(+), 33 deletions(-) create mode 100644 img/readme/quickstart/write/dynamicHeadWrite.png create mode 100644 src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java create mode 100644 src/test/java/com/alibaba/easyexcel/test/demo/write/LongestMatchColumnWidthData.java diff --git a/img/readme/quickstart/write/dynamicHeadWrite.png b/img/readme/quickstart/write/dynamicHeadWrite.png new file mode 100644 index 0000000000000000000000000000000000000000..3b25ad72b894131a3fadf7707bf7eb6a1cd0d52e GIT binary patch literal 4649 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 literal 0 HcmV?d00001 diff --git a/quickstart.md b/quickstart.md index 030a80a5..4b2d4ac1 100644 --- a/quickstart.md +++ b/quickstart.md @@ -21,6 +21,7 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja * [自定义样式](#styleWrite) * [合并单元格](#mergeWrite) * [使用table去写入](#tableWrite) +* [动态头,实时生成头写入](#dynamicHeadWrite) * [web中的写](#webWrite) ## 读excel样例 @@ -697,6 +698,47 @@ public class WidthAndHeightData { } ``` +### 动态头,实时生成头写入 +##### excel示例 +![img](img/readme/quickstart/write/dynamicHeadWrite.png) +##### 对象 +参照:[对象](#simpleWriteObject) +##### 代码 +```java + /** + * 动态头,实时生成头写入 + *

+ * 思路是这样子的,先创建List头格式的sheet仅仅写入头,然后通过table 不写入头的方式 去写入数据 + * + *

  • 1. 创建excel对应的实体对象 参照{@link DemoData} + *
  • 2. 然后写入table即可 + */ + @Test + public void dynamicHeadWrite() { + String fileName = TestFileUtil.getPath() + "dynamicHeadWrite" + System.currentTimeMillis() + ".xlsx"; + // write的时候 不传入 class 在table的时候传入 + EasyExcelFactory.write(fileName) + // 这里放入动态头 + .head(head()).sheet("模板") + // table的时候 传入class 并且设置needHead =false + .table().head(DemoData.class).needHead(Boolean.FALSE).doWrite(data()); + } + + private List> head() { + List> list = new ArrayList>(); + List head0 = new ArrayList(); + head0.add("字符串" + System.currentTimeMillis()); + List head1 = new ArrayList(); + head1.add("数字" + System.currentTimeMillis()); + List head2 = new ArrayList(); + head2.add("日期" + System.currentTimeMillis()); + list.add(head0); + list.add(head1); + list.add(head2); + return list; + } +``` + ### 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/main/java/com/alibaba/excel/annotation/write/style/ColumnWidth.java b/src/main/java/com/alibaba/excel/annotation/write/style/ColumnWidth.java index 47ccbeeb..ae07ff00 100644 --- a/src/main/java/com/alibaba/excel/annotation/write/style/ColumnWidth.java +++ b/src/main/java/com/alibaba/excel/annotation/write/style/ColumnWidth.java @@ -15,10 +15,11 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface ColumnWidth { + /** * Column width *

    - * -1 mean the auto set width + * -1 means the default column width is used */ int value() default -1; } diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index e4dbec82..18331305 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java @@ -275,7 +275,7 @@ public class WriteContextImpl implements WriteContext { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { - ((CellWriteHandler)writeHandler).afterCellCreate(writeSheetHolder, writeTableHolder, cell, head, + ((CellWriteHandler)writeHandler).afterCellCreate(writeSheetHolder, writeTableHolder, null, cell, head, relativeRowIndex, true); } } diff --git a/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java b/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java index e6e03784..1694e5e4 100644 --- a/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java @@ -36,12 +36,12 @@ public abstract class AbstractHolder implements ConfigurationHolder { public AbstractHolder(BasicParameter basicParameter, AbstractHolder prentAbstractHolder) { this.newInitialization = Boolean.TRUE; - if (basicParameter.getHead() == null && prentAbstractHolder != null) { + if (basicParameter.getHead() == null && basicParameter.getClazz() == null && prentAbstractHolder != null) { this.head = prentAbstractHolder.getHead(); } else { this.head = basicParameter.getHead(); } - if (basicParameter.getClazz() == null && prentAbstractHolder != null) { + if (basicParameter.getHead() == null && basicParameter.getClazz() == null && prentAbstractHolder != null) { this.clazz = prentAbstractHolder.getClazz(); } else { this.clazz = basicParameter.getClazz(); diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java index a15ed79d..25dee195 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java @@ -179,8 +179,8 @@ public class ExcelBuilderImpl implements ExcelBuilder { beforeCellCreate(row, head, relativeRowIndex); Cell cell = WorkBookUtil.createCell(row, cellIndex); Object value = oneRowData.get(dataIndex); - converterAndSet(context.currentWriteHolder(), value.getClass(), cell, value, null); - afterCellCreate(head, cell, relativeRowIndex); + CellData cellData = converterAndSet(context.currentWriteHolder(), value.getClass(), cell, value, null); + afterCellCreate(head, cellData, cell, relativeRowIndex); } private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex, List fieldList) { @@ -202,9 +202,9 @@ public class ExcelBuilderImpl implements ExcelBuilder { beforeCellCreate(row, head, relativeRowIndex); Cell cell = WorkBookUtil.createCell(row, cellIndex); Object value = beanMap.get(name); - converterAndSet(currentWriteHolder, excelContentProperty.getField().getType(), cell, value, - excelContentProperty); - afterCellCreate(head, cell, relativeRowIndex); + CellData cellData = converterAndSet(currentWriteHolder, excelContentProperty.getField().getType(), cell, + value, excelContentProperty); + afterCellCreate(head, cellData, cell, relativeRowIndex); beanMapHandledSet.add(name); } // Finish @@ -229,8 +229,8 @@ public class ExcelBuilderImpl implements ExcelBuilder { } beforeCellCreate(row, null, relativeRowIndex); Cell cell = WorkBookUtil.createCell(row, cellIndex++); - converterAndSet(currentWriteHolder, value.getClass(), cell, value, null); - afterCellCreate(null, cell, relativeRowIndex); + CellData cellData = converterAndSet(currentWriteHolder, value.getClass(), cell, value, null); + afterCellCreate(null, cellData, cell, relativeRowIndex); } } @@ -261,7 +261,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { } - private void afterCellCreate(Head head, Cell cell, int relativeRowIndex) { + private void afterCellCreate(Head head, CellData cellData, Cell cell, int relativeRowIndex) { List handlerList = context.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; @@ -269,7 +269,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { ((CellWriteHandler)writeHandler).afterCellCreate(context.writeSheetHolder(), context.writeTableHolder(), - cell, head, relativeRowIndex, false); + cellData, cell, head, relativeRowIndex, false); } } if (null != context.writeWorkbookHolder().getWriteWorkbook().getWriteHandler()) { @@ -277,10 +277,10 @@ public class ExcelBuilderImpl implements ExcelBuilder { } } - private void converterAndSet(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, + private CellData converterAndSet(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, ExcelContentProperty excelContentProperty) { if (value == null) { - return; + return null; } if (value instanceof String && currentWriteHolder.globalConfiguration().getAutoTrim()) { value = ((String)value).trim(); @@ -296,13 +296,13 @@ public class ExcelBuilderImpl implements ExcelBuilder { switch (cellData.getType()) { case STRING: cell.setCellValue(cellData.getStringValue()); - return; + return cellData; case BOOLEAN: cell.setCellValue(cellData.getBooleanValue()); - return; + return cellData; case NUMBER: cell.setCellValue(cellData.getDoubleValue()); - return; + return cellData; default: throw new ExcelDataConvertException("Not supported data:" + value + " return type:" + cell.getCellType() + "at row:" + cell.getRow().getRowNum()); diff --git a/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java index 38e6f407..9e8af22b 100644 --- a/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java @@ -3,6 +3,7 @@ package com.alibaba.excel.write.handler; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; +import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; @@ -36,9 +37,11 @@ public interface CellWriteHandler extends WriteHandler { * Nullable * @param cell * @param head + * @param cellData + * Nullable. * @param relativeRowIndex * @param isHead */ - void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, - int relativeRowIndex, boolean isHead); + void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, + Cell cell, Head head, int relativeRowIndex, boolean isHead); } diff --git a/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java b/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java index 9cb71f6e..09513562 100644 --- a/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java +++ b/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java @@ -4,6 +4,7 @@ import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; +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; @@ -22,8 +23,8 @@ public abstract class AbstractMergeStrategy implements CellWriteHandler { } @Override - public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, - Head head, int relativeRowIndex, boolean isHead) { + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, + Head head, int relativeRowIndex, boolean isHead) { if (isHead) { return; } diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java index 6adb4089..51b03d13 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java @@ -5,6 +5,7 @@ import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Workbook; import com.alibaba.excel.event.NotRepeatExecutor; +import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.SheetWriteHandler; @@ -46,8 +47,8 @@ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, She } @Override - public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, - Head head, int relativeRowIndex, boolean isHead) { + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, + Cell cell, Head head, int relativeRowIndex, boolean isHead) { if (isHead) { setHeadCellStyle(cell, head, relativeRowIndex); } else { diff --git a/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java index 4d2d0afe..67e9733a 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java @@ -2,9 +2,9 @@ package com.alibaba.excel.write.style.column; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; import com.alibaba.excel.event.NotRepeatExecutor; +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; @@ -29,20 +29,22 @@ public abstract class AbstractColumnWidthStyleStrategy implements CellWriteHandl } @Override - public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, - Head head, int relativeRowIndex, boolean isHead) { - setColumnWidth(writeSheetHolder.getSheet(), cell, head, relativeRowIndex, isHead); + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, + Cell cell, Head head, int relativeRowIndex, boolean isHead) { + setColumnWidth(writeSheetHolder, cellData, cell, head, relativeRowIndex, isHead); } /** * Sets the column width when head create * - * @param sheet + * @param writeSheetHolder + * @param cellData * @param cell * @param head * @param relativeRowIndex * @param isHead */ - protected abstract void setColumnWidth(Sheet sheet, Cell cell, Head head, int relativeRowIndex, boolean isHead); + protected abstract void setColumnWidth(WriteSheetHolder writeSheetHolder, CellData cellData, Cell cell, Head head, + int relativeRowIndex, boolean isHead); } diff --git a/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java index 59050430..802f15f2 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java @@ -1,9 +1,10 @@ package com.alibaba.excel.write.style.column; import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Sheet; +import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; /** * Returns the column width according to each column header @@ -12,14 +13,15 @@ import com.alibaba.excel.metadata.Head; */ public abstract class AbstractHeadColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy { @Override - protected void setColumnWidth(Sheet sheet, Cell cell, Head head, int relativeRowIndex, boolean isHead) { + protected void setColumnWidth(WriteSheetHolder writeSheetHolder, CellData cellData, Cell cell, Head head, + int relativeRowIndex, boolean isHead) { if (!isHead && relativeRowIndex != 0) { return; } Integer width = columnWidth(head); if (width != null) { width = width * 256; - sheet.setColumnWidth(cell.getColumnIndex(), width); + writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), width); } } diff --git a/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java new file mode 100644 index 00000000..5c6ec8c9 --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java @@ -0,0 +1,66 @@ +package com.alibaba.excel.write.style.column; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.poi.ss.usermodel.Cell; + +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; + +/** + * Take the width of the longest column as the width. + *

    + * This is not very useful at the moment, for example if you have Numbers it will cause a newline.And the length is not + * exactly the same as the actual length. + * + * @author Jiaju Zhuang + */ +public class LongestMatchColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy { + + private static final int MAX_COLUMN_WIDTH = 256; + + Map> cache = new HashMap>(8); + + @Override + protected void setColumnWidth(WriteSheetHolder writeSheetHolder, CellData cellData, Cell cell, Head head, + int relativeRowIndex, boolean isHead) { + if (!isHead && cellData == null) { + return; + } + Map maxColumnWidthMap = cache.get(writeSheetHolder.getSheetNo()); + if (maxColumnWidthMap == null) { + maxColumnWidthMap = new HashMap(16); + cache.put(writeSheetHolder.getSheetNo(), maxColumnWidthMap); + } + Integer columnWidth = dataLength(cellData, cell, isHead); + if (columnWidth < 0) { + return; + } + if (columnWidth > MAX_COLUMN_WIDTH) { + columnWidth = MAX_COLUMN_WIDTH; + } + Integer maxColumnWidth = maxColumnWidthMap.get(head.getColumnIndex()); + if (maxColumnWidth == null || columnWidth > maxColumnWidth) { + maxColumnWidthMap.put(head.getColumnIndex(), columnWidth); + writeSheetHolder.getSheet().setColumnWidth(head.getColumnIndex(), columnWidth * 256); + } + } + + private Integer dataLength(CellData cellData, Cell cell, boolean isHead) { + if (isHead) { + return cell.getStringCellValue().getBytes().length; + } + switch (cellData.getType()) { + case STRING: + return cellData.getStringValue().getBytes().length; + case BOOLEAN: + return cellData.getBooleanValue().toString().getBytes().length; + case NUMBER: + return cellData.getDoubleValue().toString().getBytes().length; + default: + return -1; + } + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/LongestMatchColumnWidthData.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/LongestMatchColumnWidthData.java new file mode 100644 index 00000000..69ad51dc --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/LongestMatchColumnWidthData.java @@ -0,0 +1,22 @@ +package com.alibaba.easyexcel.test.demo.write; + +import java.util.Date; + +import com.alibaba.excel.annotation.ExcelProperty; + +import lombok.Data; + +/** + * 基础数据类 + * + * @author Jiaju Zhuang + **/ +@Data +public class LongestMatchColumnWidthData { + @ExcelProperty("字符串标题") + private String string; + @ExcelProperty("日期标题很长日期标题很长日期标题很长很长") + private Date date; + @ExcelProperty("数字") + private Double doubleData; +} 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 0888b36c..d105fb76 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 @@ -25,6 +25,7 @@ import com.alibaba.excel.write.metadata.WriteTable; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; /** * 写的常见写法 @@ -218,6 +219,70 @@ public class WriteTest { excelWriter.finish(); } + /** + * 动态头,实时生成头写入 + *

    + * 思路是这样子的,先创建List头格式的sheet仅仅写入头,然后通过table 不写入头的方式 去写入数据 + * + *

  • 1. 创建excel对应的实体对象 参照{@link DemoData} + *
  • 2. 然后写入table即可 + */ + @Test + public void dynamicHeadWrite() { + String fileName = TestFileUtil.getPath() + "dynamicHeadWrite" + System.currentTimeMillis() + ".xlsx"; + // write的时候 不传入 class 在table的时候传入 + EasyExcelFactory.write(fileName) + // 这里放入动态头 + .head(head()).sheet("模板") + // table的时候 传入class 并且设置needHead =false + .table().head(DemoData.class).needHead(Boolean.FALSE).doWrite(data()); + } + + /** + * 自动列宽(不太精确) + *

    + * 这个目前不是很好用,比如有数字就会导致换行。而且长度也不是刚好和实际长度一致。 所以需要精确到刚好列宽的慎用。 当然也可以自己参照 + * {@link LongestMatchColumnWidthStyleStrategy}重新实现. + * + *

  • 1. 创建excel对应的实体对象 参照{@link DemoData} + *
  • 3. 注册策略{@link LongestMatchColumnWidthStyleStrategy} + *
  • 2. 直接写即可 + */ + @Test + public void longestMatchColumnWidthWrite() { + String fileName = + TestFileUtil.getPath() + "longestMatchColumnWidthWrite" + System.currentTimeMillis() + ".xlsx"; + // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + EasyExcelFactory.write(fileName, LongestMatchColumnWidthData.class) + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("模板").doWrite(dataLong()); + } + + private List dataLong() { + List list = new ArrayList(); + for (int i = 0; i < 10; i++) { + LongestMatchColumnWidthData data = new LongestMatchColumnWidthData(); + data.setString("测试很长的字符串测试很长的字符串测试很长的字符串" + i); + data.setDate(new Date()); + data.setDoubleData(1000000000000.0); + list.add(data); + } + return list; + } + + private List> head() { + List> list = new ArrayList>(); + List head0 = new ArrayList(); + head0.add("字符串" + System.currentTimeMillis()); + List head1 = new ArrayList(); + head1.add("数字" + System.currentTimeMillis()); + List head2 = new ArrayList(); + head2.add("日期" + System.currentTimeMillis()); + list.add(head0); + list.add(head1); + list.add(head2); + return list; + } + private List data() { List list = new ArrayList(); for (int i = 0; i < 10; i++) {