Browse Source

完成图片写入测试

pull/2074/head
Jiaju Zhuang 4 years ago
parent
commit
b435424383
  1. 1
      pom.xml
  2. 3
      src/main/java/com/alibaba/excel/metadata/data/ClientAnchorData.java
  3. 2
      src/main/java/com/alibaba/excel/util/MapUtils.java
  4. 5
      src/main/java/com/alibaba/excel/util/StyleUtil.java
  5. 19
      src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java
  6. 4
      src/main/java/com/alibaba/excel/write/metadata/RowData.java
  7. 10
      src/test/java/com/alibaba/easyexcel/test/demo/write/ImageDemoData.java
  8. 66
      src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java

1
pom.xml

@ -163,6 +163,7 @@
<exclude>com/alibaba/excel/event/AnalysisEventListener.java</exclude> <exclude>com/alibaba/excel/event/AnalysisEventListener.java</exclude>
<exclude>com/alibaba/excel/metadata/DataFormatter.java</exclude> <exclude>com/alibaba/excel/metadata/DataFormatter.java</exclude>
<exclude>com/alibaba/excel/util/DateUtils.java</exclude> <exclude>com/alibaba/excel/util/DateUtils.java</exclude>
<exclude>com/alibaba/excel/util/MapUtils.java</exclude>
<exclude>com/alibaba/excel/metadata/format/DataFormatter.java</exclude> <exclude>com/alibaba/excel/metadata/format/DataFormatter.java</exclude>
<exclude>com/alibaba/excel/metadata/format/ExcelGeneralNumberFormat.java</exclude> <exclude>com/alibaba/excel/metadata/format/ExcelGeneralNumberFormat.java</exclude>
</excludes> </excludes>

3
src/main/java/com/alibaba/excel/metadata/data/ClientAnchorData.java

@ -102,8 +102,7 @@ public class ClientAnchorData extends CoordinateData {
ClientAnchor.AnchorType value; ClientAnchor.AnchorType value;
// disallow non-sequential enum instance creation AnchorType(ClientAnchor.AnchorType value) {
private AnchorType(ClientAnchor.AnchorType value) {
this.value = value; this.value = value;
} }

2
src/main/java/com/alibaba/excel/util/MapUtils.java

@ -27,7 +27,7 @@ public class MapUtils {
* @return a new, empty {@code HashMap} * @return a new, empty {@code HashMap}
*/ */
public static <K, V> HashMap<K, V> newHashMap() { public static <K, V> HashMap<K, V> newHashMap() {
return new HashMap<>(); return new HashMap<>(16);
} }
/** /**

5
src/main/java/com/alibaba/excel/util/StyleUtil.java

@ -18,6 +18,7 @@ import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.Units;
import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.apache.poi.xssf.usermodel.XSSFRichTextString;
/** /**
@ -25,8 +26,6 @@ import org.apache.poi.xssf.usermodel.XSSFRichTextString;
*/ */
public class StyleUtil { public class StyleUtil {
public static int baseCoordinate = 10000;
private StyleUtil() {} private StyleUtil() {}
/** /**
@ -191,7 +190,7 @@ public class StyleUtil {
if (coordinate == null) { if (coordinate == null) {
return 0; return 0;
} }
return baseCoordinate * coordinate; return Units.toEMU(coordinate);
} }
public static int getCellCoordinate(Integer currentCoordinate, Integer absoluteCoordinate, public static int getCellCoordinate(Integer currentCoordinate, Integer absoluteCoordinate,

19
src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java

@ -32,6 +32,7 @@ import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
@ -61,6 +62,8 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
// Fill in picture information // Fill in picture information
fillImage(cell, cellData.getImageDataList()); fillImage(cell, cellData.getImageDataList());
//setImageValue(cellData,cell);
// Fill in comment information // Fill in comment information
fillComment(cell, cellData.getCommentData()); fillComment(cell, cellData.getCommentData());
@ -197,10 +200,10 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
anchor.setDy1(StyleUtil.getCoordinate(imageData.getTop())); anchor.setDy1(StyleUtil.getCoordinate(imageData.getTop()));
} }
if (imageData.getRight() != null) { if (imageData.getRight() != null) {
anchor.setDx2(StyleUtil.getCoordinate(imageData.getRight())); anchor.setDx2(-StyleUtil.getCoordinate(imageData.getRight()));
} }
if (imageData.getBottom() != null) { if (imageData.getBottom() != null) {
anchor.setDy2(StyleUtil.getCoordinate(imageData.getBottom())); anchor.setDy2(-StyleUtil.getCoordinate(imageData.getBottom()));
} }
if (imageData.getLeft() != null) { if (imageData.getLeft() != null) {
anchor.setDx1(StyleUtil.getCoordinate(imageData.getLeft())); anchor.setDx1(StyleUtil.getCoordinate(imageData.getLeft()));
@ -210,20 +213,24 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
anchor.setCol1(StyleUtil.getCellCoordinate(cell.getColumnIndex(), imageData.getFirstColumnIndex(), anchor.setCol1(StyleUtil.getCellCoordinate(cell.getColumnIndex(), imageData.getFirstColumnIndex(),
imageData.getRelativeFirstColumnIndex())); imageData.getRelativeFirstColumnIndex()));
anchor.setRow2(StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), imageData.getLastRowIndex(), anchor.setRow2(StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), imageData.getLastRowIndex(),
imageData.getRelativeLastRowIndex())); imageData.getRelativeLastRowIndex()) + 1);
anchor.setCol2(StyleUtil.getCellCoordinate(cell.getColumnIndex(), imageData.getLastColumnIndex(), anchor.setCol2(StyleUtil.getCellCoordinate(cell.getColumnIndex(), imageData.getLastColumnIndex(),
imageData.getRelativeLastColumnIndex())); imageData.getRelativeLastColumnIndex()) + 1);
if (imageData.getAnchorType() != null) { if (imageData.getAnchorType() != null) {
anchor.setAnchorType(imageData.getAnchorType().getValue()); anchor.setAnchorType(imageData.getAnchorType().getValue());
} }
drawing.createPicture(anchor, index); Picture picture = drawing.createPicture(anchor, index);
//picture.resize(0.5, 0.5);
} }
} }
protected WriteCellData<?> convert(WriteHolder currentWriteHolder, Class<?> clazz, CellDataTypeEnum targetType, protected WriteCellData<?> convert(WriteHolder currentWriteHolder, Class<?> clazz, CellDataTypeEnum targetType,
Cell cell, Object value, ExcelContentProperty excelContentProperty) { Cell cell, Object value, ExcelContentProperty excelContentProperty) {
// This means that the user has defined the data. // This means that the user has defined the data.
if (value instanceof WriteCellData) { if (clazz == WriteCellData.class) {
if (value == null) {
return new WriteCellData<>(CellDataTypeEnum.EMPTY);
}
WriteCellData<?> cellDataValue = (WriteCellData<?>)value; WriteCellData<?> cellDataValue = (WriteCellData<?>)value;
if (cellDataValue.getType() != null) { if (cellDataValue.getType() != null) {
return cellDataValue; return cellDataValue;

4
src/main/java/com/alibaba/excel/write/metadata/RowData.java

@ -6,9 +6,13 @@ package com.alibaba.excel.write.metadata;
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
public interface RowData { public interface RowData {
/** /**
* Returns the value to which the specified key is mapped, * Returns the value to which the specified key is mapped,
* or {@code null} if this map contains no mapping for the key. * or {@code null} if this map contains no mapping for the key.
*
* @param index
* @return data
*/ */
Object get(int index); Object get(int index);

10
src/test/java/com/alibaba/easyexcel/test/demo/write/ImageData.java → src/test/java/com/alibaba/easyexcel/test/demo/write/ImageDemoData.java

@ -8,6 +8,7 @@ import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.converters.string.StringImageConverter; import com.alibaba.excel.converters.string.StringImageConverter;
import com.alibaba.excel.metadata.data.WriteCellData;
import lombok.Data; import lombok.Data;
@ -19,7 +20,7 @@ import lombok.Data;
@Data @Data
@ContentRowHeight(100) @ContentRowHeight(100)
@ColumnWidth(100 / 8) @ColumnWidth(100 / 8)
public class ImageData { public class ImageDemoData {
private File file; private File file;
private InputStream inputStream; private InputStream inputStream;
/** /**
@ -34,4 +35,11 @@ public class ImageData {
* @since 2.1.1 * @since 2.1.1
*/ */
private URL url; private URL url;
/**
* 根据文件导出 并设置导出的位置
*
* @since 3.0.0-beta1
*/
private WriteCellData<Void> writeCellDataFile;
} }

66
src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java

@ -18,6 +18,10 @@ import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight; import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.ImageData;
import com.alibaba.excel.metadata.data.ImageData.ImageType;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.write.merge.LoopMergeStrategy; import com.alibaba.excel.write.merge.LoopMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
@ -194,7 +198,8 @@ public class WriteTest {
excelWriter = EasyExcel.write(fileName).build(); excelWriter = EasyExcel.write(fileName).build();
// 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面 // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
// 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class 实际上可以一直变 // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class
// 实际上可以一直变
WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).head(DemoData.class).build(); WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).head(DemoData.class).build();
// 分页去数据库查询数据 这里可以去数据库查询每一页的数据 // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
List<DemoData> data = data(); List<DemoData> data = data();
@ -227,7 +232,7 @@ public class WriteTest {
/** /**
* 图片导出 * 图片导出
* <p> * <p>
* 1. 创建excel对应的实体对象 参照{@link ImageData} * 1. 创建excel对应的实体对象 参照{@link ImageDemoData}
* <p> * <p>
* 2. 直接写即可 * 2. 直接写即可
*/ */
@ -237,19 +242,49 @@ public class WriteTest {
// 如果使用流 记得关闭 // 如果使用流 记得关闭
InputStream inputStream = null; InputStream inputStream = null;
try { try {
List<ImageData> list = new ArrayList<ImageData>(); List<ImageDemoData> list = new ArrayList<>();
ImageData imageData = new ImageData(); ImageDemoData imageDemoData = new ImageDemoData();
list.add(imageData); list.add(imageDemoData);
String imagePath = TestFileUtil.getPath() + "converter" + File.separator + "img.jpg"; String imagePath = TestFileUtil.getPath() + "converter" + File.separator + "img.jpg";
// 放入五种类型的图片 实际使用只要选一种即可 // 放入五种类型的图片 实际使用只要选一种即可
imageData.setByteArray(FileUtils.readFileToByteArray(new File(imagePath))); imageDemoData.setByteArray(FileUtils.readFileToByteArray(new File(imagePath)));
imageData.setFile(new File(imagePath)); imageDemoData.setFile(new File(imagePath));
imageData.setString(imagePath); imageDemoData.setString(imagePath);
inputStream = FileUtils.openInputStream(new File(imagePath)); inputStream = FileUtils.openInputStream(new File(imagePath));
imageData.setInputStream(inputStream); imageDemoData.setInputStream(inputStream);
imageData.setUrl(new URL( imageDemoData.setUrl(new URL(
"https://raw.githubusercontent.com/alibaba/easyexcel/master/src/test/resources/converter/img.jpg")); "https://raw.githubusercontent.com/alibaba/easyexcel/master/src/test/resources/converter/img.jpg"));
EasyExcel.write(fileName, ImageData.class).sheet().doWrite(list);
// 这里演示 图片 不想顶格放 且占用2个单元格的情况
WriteCellData<Void> writeCellData = new WriteCellData<>();
imageDemoData.setWriteCellDataFile(writeCellData);
// 设置为空 代表当前单元格不需要写图片以外的数据
writeCellData.setType(CellDataTypeEnum.EMPTY);
// 可以放入多个图片
List<ImageData> imageDataList = new ArrayList<>();
ImageData imageData = new ImageData();
imageDataList.add(imageData);
writeCellData.setImageDataList(imageDataList);
// 放入2进制图片
imageData.setImage(FileUtils.readFileToByteArray(new File(imagePath)));
// 图片类型
imageData.setImageType(ImageType.PICTURE_TYPE_PNG);
// 上 右 下 左 需要留空
// 这里实测 不能设置太大 超过单元格原始大小后 打开会提示修复。暂时未找到很好的解法。
imageData.setTop(5);
imageData.setRight(5);
imageData.setBottom(5);
imageData.setLeft(5);
// 设置图片的位置 假设 现在目标 是 覆盖 当前单元格 和当前单元格右边的单元格
// 起点相对于当前单元格为0 当然可以不写
imageData.setRelativeFirstRowIndex(0);
imageData.setRelativeFirstColumnIndex(0);
imageData.setRelativeLastRowIndex(0);
// 前面3个可以不写 下面这个需要写 也就是 结尾 需要相对当前单元格 往右移动一格
imageData.setRelativeLastColumnIndex(1);
// 写入数据
EasyExcel.write(fileName, ImageDemoData.class).sheet().doWrite(list);
} finally { } finally {
if (inputStream != null) { if (inputStream != null) {
inputStream.close(); inputStream.close();
@ -325,7 +360,7 @@ public class WriteTest {
// 背景设置为红色 // 背景设置为红色
headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
WriteFont headWriteFont = new WriteFont(); WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short) 20); headWriteFont.setFontHeightInPoints((short)20);
headWriteCellStyle.setWriteFont(headWriteFont); headWriteCellStyle.setWriteFont(headWriteFont);
// 内容的策略 // 内容的策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
@ -335,7 +370,7 @@ public class WriteTest {
contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
WriteFont contentWriteFont = new WriteFont(); WriteFont contentWriteFont = new WriteFont();
// 字体大小 // 字体大小
contentWriteFont.setFontHeightInPoints((short) 20); contentWriteFont.setFontHeightInPoints((short)20);
contentWriteCellStyle.setWriteFont(contentWriteFont); contentWriteCellStyle.setWriteFont(contentWriteFont);
// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现 // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
HorizontalCellStyleStrategy horizontalCellStyleStrategy = HorizontalCellStyleStrategy horizontalCellStyleStrategy =
@ -428,7 +463,8 @@ public class WriteTest {
/** /**
* 自动列宽(不太精确) * 自动列宽(不太精确)
* <p> * <p>
* 这个目前不是很好用比如有数字就会导致换行而且长度也不是刚好和实际长度一致 所以需要精确到刚好列宽的慎用 当然也可以自己参照 {@link LongestMatchColumnWidthStyleStrategy}重新实现. * 这个目前不是很好用比如有数字就会导致换行而且长度也不是刚好和实际长度一致 所以需要精确到刚好列宽的慎用 当然也可以自己参照 {@link LongestMatchColumnWidthStyleStrategy}
* 重新实现.
* <p> * <p>
* poi 自带{@link SXSSFSheet#autoSizeColumn(int)} 对中文支持也不太好目前没找到很好的算法 有的话可以推荐下 * poi 自带{@link SXSSFSheet#autoSizeColumn(int)} 对中文支持也不太好目前没找到很好的算法 有的话可以推荐下
* *

Loading…
Cancel
Save