Browse Source

Add new feature: use annotation to set image position

pull/1198/head
dota17 5 years ago
parent
commit
59f90ba782
  1. 61
      src/main/java/com/alibaba/excel/annotation/write/style/ImagePosition.java
  2. 8
      src/main/java/com/alibaba/excel/converters/bytearray/BoxingByteArrayImageConverter.java
  3. 8
      src/main/java/com/alibaba/excel/converters/bytearray/ByteArrayImageConverter.java
  4. 8
      src/main/java/com/alibaba/excel/converters/file/FileImageConverter.java
  5. 8
      src/main/java/com/alibaba/excel/converters/inputstream/InputStreamImageConverter.java
  6. 8
      src/main/java/com/alibaba/excel/converters/string/StringImageConverter.java
  7. 45
      src/main/java/com/alibaba/excel/metadata/CellData.java
  8. 132
      src/main/java/com/alibaba/excel/metadata/property/ImagePositionProperty.java
  9. 12
      src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java
  10. 42
      src/test/java/com/alibaba/easyexcel/test/demo/write/ImageDataWithAnnotation.java
  11. 33
      src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java

61
src/main/java/com/alibaba/excel/annotation/write/style/ImagePosition.java

@ -0,0 +1,61 @@
package com.alibaba.excel.annotation.write.style;
import org.apache.poi.ss.usermodel.ClientAnchor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
/**
* This annotation is used to set the position of a picture.
* See {@link ClientAnchor}
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ImagePosition {
/**
* The x coordinate within the first cell.
*/
int dx1();
/**
* The y coordinate within the first cell.
*/
int dy1();
/**
* The x coordinate within the second cell.
*/
int dx2();
/**
* The y coordinate within the second cell
*/
int dy2();
/**
* 0-based column of the first cell.
*/
short col1();
/**
* 0-based row of the first cell.
*/
int row1();
/**
* 0-based column of the second cell.
*/
short col2();
/**
* 0-based row of the second cell.
*/
int row2();
}

8
src/main/java/com/alibaba/excel/converters/bytearray/BoxingByteArrayImageConverter.java

@ -1,5 +1,8 @@
package com.alibaba.excel.converters.bytearray; package com.alibaba.excel.converters.bytearray;
import java.lang.annotation.Annotation;
import com.alibaba.excel.annotation.write.style.ImagePosition;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
@ -35,7 +38,12 @@ public class BoxingByteArrayImageConverter implements Converter<Byte[]> {
for (int i = 0; i < value.length; i++) { for (int i = 0; i < value.length; i++) {
byteValue[i] = value[i]; byteValue[i] = value[i];
} }
ImagePosition imagePosition = contentProperty.getField().getAnnotation(ImagePosition.class);
if (imagePosition != null) {
return new CellData(byteValue, imagePosition);
} else {
return new CellData(byteValue); return new CellData(byteValue);
} }
}
} }

8
src/main/java/com/alibaba/excel/converters/bytearray/ByteArrayImageConverter.java

@ -1,5 +1,8 @@
package com.alibaba.excel.converters.bytearray; package com.alibaba.excel.converters.bytearray;
import java.lang.annotation.Annotation;
import com.alibaba.excel.annotation.write.style.ImagePosition;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
@ -31,7 +34,12 @@ public class ByteArrayImageConverter implements Converter<byte[]> {
@Override @Override
public CellData convertToExcelData(byte[] value, ExcelContentProperty contentProperty, public CellData convertToExcelData(byte[] value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
ImagePosition imagePosition = contentProperty.getField().getAnnotation(ImagePosition.class);
if (imagePosition != null) {
return new CellData(value, imagePosition);
} else {
return new CellData(value); return new CellData(value);
} }
}
} }

8
src/main/java/com/alibaba/excel/converters/file/FileImageConverter.java

@ -2,7 +2,7 @@ package com.alibaba.excel.converters.file;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import com.alibaba.excel.annotation.write.style.ImagePosition;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
@ -35,7 +35,11 @@ public class FileImageConverter implements Converter<File> {
@Override @Override
public CellData convertToExcelData(File value, ExcelContentProperty contentProperty, public CellData convertToExcelData(File value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws IOException { GlobalConfiguration globalConfiguration) throws IOException {
ImagePosition imagePosition = contentProperty.getField().getAnnotation(ImagePosition.class);
if (imagePosition != null) {
return new CellData(FileUtils.readFileToByteArray(value), imagePosition);
} else {
return new CellData(FileUtils.readFileToByteArray(value)); return new CellData(FileUtils.readFileToByteArray(value));
} }
}
} }

8
src/main/java/com/alibaba/excel/converters/inputstream/InputStreamImageConverter.java

@ -2,12 +2,15 @@ package com.alibaba.excel.converters.inputstream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.annotation.Annotation;
import com.alibaba.excel.annotation.write.style.ImagePosition;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.IoUtils; import com.alibaba.excel.util.IoUtils;
/** /**
@ -35,7 +38,12 @@ public class InputStreamImageConverter implements Converter<InputStream> {
@Override @Override
public CellData convertToExcelData(InputStream value, ExcelContentProperty contentProperty, public CellData convertToExcelData(InputStream value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws IOException { GlobalConfiguration globalConfiguration) throws IOException {
ImagePosition imagePosition = contentProperty.getField().getAnnotation(ImagePosition.class);
if (imagePosition != null) {
return new CellData(IoUtils.toByteArray(value), imagePosition);
} else {
return new CellData(IoUtils.toByteArray(value)); return new CellData(IoUtils.toByteArray(value));
} }
}
} }

8
src/main/java/com/alibaba/excel/converters/string/StringImageConverter.java

@ -2,13 +2,16 @@ package com.alibaba.excel.converters.string;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Annotation;
import com.alibaba.excel.annotation.write.style.ImagePosition;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.IoUtils;
/** /**
* String and image converter * String and image converter
@ -35,7 +38,12 @@ public class StringImageConverter implements Converter<String> {
@Override @Override
public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, public CellData convertToExcelData(String value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws IOException { GlobalConfiguration globalConfiguration) throws IOException {
ImagePosition imagePosition = contentProperty.getField().getAnnotation(ImagePosition.class);
if (imagePosition != null) {
return new CellData(FileUtils.readFileToByteArray(new File(value)), imagePosition);
} else {
return new CellData(FileUtils.readFileToByteArray(new File(value))); return new CellData(FileUtils.readFileToByteArray(new File(value)));
} }
}
} }

45
src/main/java/com/alibaba/excel/metadata/CellData.java

@ -1,8 +1,9 @@
package com.alibaba.excel.metadata; package com.alibaba.excel.metadata;
import java.math.BigDecimal; import java.math.BigDecimal;
import com.alibaba.excel.annotation.write.style.ImagePosition;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.property.ImagePositionProperty;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
/** /**
@ -29,6 +30,16 @@ public class CellData<T> extends AbstractCell {
private Boolean formula; private Boolean formula;
private String formulaValue; private String formulaValue;
private byte[] imageValue; private byte[] imageValue;
/**
* Keep the information of image position in annotation.
*/
private ImagePositionProperty imagePositionProperty;
/**
* It will be set true when using annotation to set the image's position.
*/
private Boolean useImagePositionProperty = false;
/** /**
* The number formatting.Currently only supported when reading * The number formatting.Currently only supported when reading
*/ */
@ -50,6 +61,8 @@ public class CellData<T> extends AbstractCell {
this.formula = other.formula; this.formula = other.formula;
this.formulaValue = other.formulaValue; this.formulaValue = other.formulaValue;
this.imageValue = other.imageValue; this.imageValue = other.imageValue;
this.imagePositionProperty = other.imagePositionProperty;
this.useImagePositionProperty = other.useImagePositionProperty;
this.dataFormat = other.dataFormat; this.dataFormat = other.dataFormat;
this.dataFormatString = other.dataFormatString; this.dataFormatString = other.dataFormatString;
this.data = other.data; this.data = other.data;
@ -101,6 +114,20 @@ public class CellData<T> extends AbstractCell {
this.formula = Boolean.FALSE; this.formula = Boolean.FALSE;
} }
public CellData(byte[] imageValue, ImagePosition imagePosition) {
if (imageValue == null) {
throw new IllegalArgumentException("ImageValue can not be null");
}
if (imagePosition == null) {
throw new IllegalArgumentException("ImagePosition can not be null");
}
this.type = CellDataTypeEnum.IMAGE;
this.imageValue = imageValue;
this.imagePositionProperty = ImagePositionProperty.build(imagePosition);
this.useImagePositionProperty = true;
this.formula = Boolean.FALSE;
}
public CellData(Boolean booleanValue) { public CellData(Boolean booleanValue) {
if (booleanValue == null) { if (booleanValue == null) {
throw new IllegalArgumentException("BooleanValue can not be null"); throw new IllegalArgumentException("BooleanValue can not be null");
@ -174,6 +201,22 @@ public class CellData<T> extends AbstractCell {
this.imageValue = imageValue; this.imageValue = imageValue;
} }
public ImagePositionProperty getImagePositionProperty() {
return imagePositionProperty;
}
public void setImagePositionProperty(ImagePositionProperty imagePositionProperty) {
this.imagePositionProperty = imagePositionProperty;
}
public Boolean getUseImagePositionProperty() {
return useImagePositionProperty;
}
public void setUseImagePositionProperty(Boolean useImagePositionProperty) {
this.useImagePositionProperty = useImagePositionProperty;
}
public Integer getDataFormat() { public Integer getDataFormat() {
return dataFormat; return dataFormat;
} }

132
src/main/java/com/alibaba/excel/metadata/property/ImagePositionProperty.java

@ -0,0 +1,132 @@
package com.alibaba.excel.metadata.property;
import com.alibaba.excel.annotation.write.style.ImagePosition;
/**
* Keep the information of image position from an annotation.
*/
public class ImagePositionProperty {
/**
* The x coordinate within the first cell.
*/
private int dx1;
/**
* The y coordinate within the first cell.
*/
private int dy1;
/**
* The x coordinate within the second cell.
*/
private int dx2;
/**
* The y coordinate within the second cell
*/
private int dy2;
/**
* 0-based column of the first cell.
*/
private short col1;
/**
* 0-based row of the first cell.
*/
private int row1;
/**
* 0-based column of the second cell.
*/
private short col2;
/**
* 0-based row of the second cell.
*/
private int row2;
public static ImagePositionProperty build(ImagePosition imagePosition) {
if (imagePosition == null) {
return null;
}
return new ImagePositionProperty(imagePosition.dx1(), imagePosition.dy1(), imagePosition.dx2(),
imagePosition.dy2(), imagePosition.col1(), imagePosition.row1(), imagePosition.col2(), imagePosition.row2());
}
public ImagePositionProperty(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2) {
this.dx1 = dx1;
this.dy1 = dy1;
this.dx2 = dx2;
this.dy2 = dy2;
this.col1 = col1;
this.row1 = row1;
this.col2 = col2;
this.row2 = row2;
}
public int getDx1() {
return dx1;
}
public void setDx1(int dx1) {
this.dx1 = dx1;
}
public int getDy1() {
return dy1;
}
public void setDy1(int dy1) {
this.dy1 = dy1;
}
public int getDx2() {
return dx2;
}
public void setDx2(int dx2) {
this.dx2 = dx2;
}
public int getDy2() {
return dy2;
}
public void setDy2(int dy2) {
this.dy2 = dy2;
}
public short getCol1() {
return col1;
}
public void setCol1(short col1) {
this.col1 = col1;
}
public int getRow1() {
return row1;
}
public void setRow1(int row1) {
this.row1 = row1;
}
public short getCol2() {
return col2;
}
public void setCol2(short col2) {
this.col2 = col2;
}
public int getRow2() {
return row2;
}
public void setRow2(int row2) {
this.row2 = row2;
}
}

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

@ -136,6 +136,17 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
} }
CreationHelper helper = sheet.getWorkbook().getCreationHelper(); CreationHelper helper = sheet.getWorkbook().getCreationHelper();
ClientAnchor anchor = helper.createClientAnchor(); ClientAnchor anchor = helper.createClientAnchor();
if(cellData.getUseImagePositionProperty()) {
anchor.setDx1(cellData.getImagePositionProperty().getDx1());
anchor.setDx2(cellData.getImagePositionProperty().getDx2());
anchor.setDy1(cellData.getImagePositionProperty().getDy1());
anchor.setDy2(cellData.getImagePositionProperty().getDy2());
anchor.setCol1(cellData.getImagePositionProperty().getCol1());
anchor.setCol2(cellData.getImagePositionProperty().getCol2());
anchor.setRow1(cellData.getImagePositionProperty().getRow1());
anchor.setRow2(cellData.getImagePositionProperty().getRow2());
anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
} else {
anchor.setDx1(0); anchor.setDx1(0);
anchor.setDx2(0); anchor.setDx2(0);
anchor.setDy1(0); anchor.setDy1(0);
@ -145,6 +156,7 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
anchor.setRow1(cell.getRowIndex()); anchor.setRow1(cell.getRowIndex());
anchor.setRow2(cell.getRowIndex() + 1); anchor.setRow2(cell.getRowIndex() + 1);
anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE); anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
}
drawing.createPicture(anchor, index); drawing.createPicture(anchor, index);
} }
} }

42
src/test/java/com/alibaba/easyexcel/test/demo/write/ImageDataWithAnnotation.java

@ -0,0 +1,42 @@
package com.alibaba.easyexcel.test.demo.write;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.ImagePosition;
import com.alibaba.excel.converters.string.StringImageConverter;
import lombok.Data;
/**
* 图片导出类
*
*/
@Data
@ContentRowHeight(100)
@ColumnWidth(100 / 8)
public class ImageDataWithAnnotation {
@ImagePosition(dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0, col1 = 0, row1 = 3, col2 = 1, row2 = 4)
private File file;
@ImagePosition(dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0, col1 = 0, row1 = 1, col2 = 2, row2 = 2)
private InputStream inputStream;
/**
* 如果string类型 必须指定转换器string默认转换成string
*/
@ExcelProperty(converter = StringImageConverter.class)
@ImagePosition(dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0, col1 = 2, row1 = 1, col2 = 3, row2 = 3)
private String string;
@ImagePosition(dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0, col1 = 3, row1 = 1, col2 = 4, row2 = 5)
private byte[] byteArray;
/**
* 根据url导出
*
* @since 2.1.1
*/
@ImagePosition(dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0, col1 = 4, row1 = 1, col2 = 5, row2 = 2)
private URL url;
}

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

@ -234,6 +234,39 @@ public class WriteTest {
} }
} }
/**
* 使用注解设置图片位置,然后导出
* <p>
* 1. 创建excel对应的实体对象 参照{@link ImageData}
* <p>
* 2. 直接写即可
*/
@Test
public void imageWriteWithAnnotation() throws Exception {
String fileName = TestFileUtil.getPath() + "imageWriteWithAnnotation" + System.currentTimeMillis() + ".xlsx";
// 如果使用流 记得关闭
InputStream inputStream = null;
try {
List<ImageDataWithAnnotation> list = new ArrayList<ImageDataWithAnnotation>();
ImageDataWithAnnotation imageData = new ImageDataWithAnnotation();
list.add(imageData);
String imagePath = TestFileUtil.getPath() + "converter" + File.separator + "img.jpg";
// 放入五种类型的图片 实际使用只要选一种即可
imageData.setByteArray(FileUtils.readFileToByteArray(new File(imagePath)));
imageData.setFile(new File(imagePath));
imageData.setString(imagePath);
inputStream = FileUtils.openInputStream(new File(imagePath));
imageData.setInputStream(inputStream);
imageData.setUrl(new URL(
"https://raw.githubusercontent.com/alibaba/easyexcel/master/src/test/resources/converter/img.jpg"));
EasyExcel.write(fileName, ImageDataWithAnnotation.class).sheet().doWrite(list);
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
/** /**
* 根据模板写入 * 根据模板写入
* <p> * <p>

Loading…
Cancel
Save