写入图片
将数据中的图片写入excel中
实体类
@Data
@ColumnWidth(100 / 8)
@ContentRowHeight(100)
public class ImageData {
private File file;
private InputStream inputStream;
@ExcelProperty(converter = StringToImageConverter.class)
private String path;
private byte[] byteArray;
private URL url;
}
@ColumnWidth(100 / 8)
:定义单元格的宽度
@ContentRowHeight(100):定义每一行的高度
转换类
public class StringToImageConverter implements Converter<String> {
@Override
public Class supportJavaTypeKey() {
return String.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.IMAGE;
}
@Override
public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
throw new UnsupportedOperationException("不支持图片读取");
}
@Override
public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
return new CellData(FileUtils.readFileToByteArray(new File(value)));
}
}
工具类
package com.example.exceltools.write;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.util.IoUtils;
import java.io.*;
/**
* @author xupu
* @description
* @date 2021/8/31 15:55:25
*/
public class FileUtils {
public static final int EOF = -1;
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
private static final int WRITE_BUFF_SIZE = 8192;
private FileUtils() {}
public static byte[] readFileToByteArray(final File file) throws IOException {
try (InputStream in = openInputStream(file)) {
final long fileLength = file.length();
return fileLength > 0 ? IoUtils.toByteArray(in, (int) fileLength) : IoUtils.toByteArray(in);
}
}
public static FileInputStream openInputStream(final File file) throws IOException {
if (file.exists()) {
if (file.isDirectory()) {
throw new IOException("File '" + file + "' exists but is a directory");
}
if (!file.canRead()) {
throw new IOException("File '" + file + "' cannot be read");
}
} else {
throw new FileNotFoundException("File '" + file + "' does not exist");
}
return new FileInputStream(file);
}
public static void writeToFile(File file, InputStream inputStream) {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
int bytesRead;
byte[] buffer = new byte[WRITE_BUFF_SIZE];
while ((bytesRead = inputStream.read(buffer, 0, WRITE_BUFF_SIZE)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
throw new ExcelAnalysisException("Can not create temporary file!", e);
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
throw new ExcelAnalysisException("Can not close 'outputStream'!", e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new ExcelAnalysisException("Can not close 'inputStream'", e);
}
}
}
}
public static byte[] toByteArray(final InputStream input) throws IOException {
final ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
copy(input, output);
return output.toByteArray();
} finally {
output.toByteArray();
}
}
/**
* Gets the contents of an InputStream as a byte[].
*
* @param input
* @param size
*
* @return
*
* @throws IOException
*/
public static byte[] toByteArray(final InputStream input, final int size) throws IOException {
if (size < 0) {
throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
}
if (size == 0) {
return new byte[0];
}
final byte[] data = new byte[size];
int offset = 0;
int read;
while (offset < size && (read = input.read(data, offset, size - offset)) != EOF) {
offset += read;
}
if (offset != size) {
throw new IOException("Unexpected read size. current: " + offset + ", expected: " + size);
}
return data;
}
/**
* Copies bytes
*
* @param input
* @param output
*
* @return
*
* @throws IOException
*/
public static int copy(final InputStream input, final OutputStream output) throws IOException {
long count = 0;
int n;
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
while (EOF != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
if (count > Integer.MAX_VALUE) {
return -1;
}
return (int) count;
}
}
实现代码
@SneakyThrows
private static void imageWrite(String filePath, String projectPath) {
// 如果使用流 记得关闭
InputStream inputStream = null;
try {
List<ImageData> list = new ArrayList<>();
String imagePath = projectPath + File.separator + "img" + File.separator + "img.jpg";
// 放入五种类型的图片 实际使用只要选一种即可
ImageData imageData = new ImageData();
imageData.setByteArray(FileUtils.readFileToByteArray(new File(imagePath)));
imageData.setFile(new File(imagePath));
inputStream = FileUtils.openInputStream(new File(imagePath));
imageData.setInputStream(inputStream);
imageData.setPath(imagePath);
imageData.setUrl(new URL("https://images.unsplash.com/photo-1630321133789-10b000def0cd?ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwyfHx8ZW58MHx8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60"));
list.add(imageData);
EasyExcel.write(filePath, ImageData.class).sheet().doWrite(list);
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
根据模板文件进行写入
设置一个模板文件,以该文件 为模板进行写入,新增sheet在模板之后
private static void templateWrite(String filePath, String tempPath, List<WriteData> list) {
EasyExcel.write(filePath, WriteData.class).withTemplate(tempPath).sheet("模板文件导出").doWrite(list);
}
列宽、行高
设置导出的excel数据的列宽、行高属性
@Data
@ContentRowHeight(10)
@HeadRowHeight(20)
@ColumnWidth(25)
public class WidthAndHeightData {
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题")
private Date date;
/**
* 宽度为50
*/
@ColumnWidth(50)
@ExcelProperty("数字标题")
private Double doubleData;
}
@ContentRowHeight(10)
:定义每一行的高度
@HeadRowHeight(20)
:定义头部每一行的高度
@ColumnWidth(25):定义每一列的宽度,可以设置总体,也可以单独设置
自定义样式
对于导出的excel,我们可以对其样式进行一些简单的设置
注解的方式
@Data
// 头背景设置成红色 IndexedColors.RED.getIndex()
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 5)
// 头字体设置成20
@HeadFontStyle(fontHeightInPoints = 16)
// 内容的背景设置成绿色 IndexedColors.GREEN.getIndex()
@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 4)
// 内容字体设置成20
@ContentFontStyle(fontHeightInPoints = 20)
public class CustomStyleData {
// 字符串的头背景设置成粉红 IndexedColors.PINK.getIndex()
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 14)
// 字符串的头字体设置成20
@HeadFontStyle(fontHeightInPoints = 30)
// 字符串的内容的背景设置成天蓝 IndexedColors.SKY_BLUE.getIndex()
@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40)
// 字符串的内容字体设置成20
@ContentFontStyle(fontHeightInPoints = 30)
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题")
private Date date;
@ExcelProperty("数字标题")
private Double doubleData;
}
编码方式实现
private static void customStyleByCode(String filePath, List<CustomStyleData> customStyleData) {
// 头的策略
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
headWriteCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short) 20);
headWriteCellStyle.setWriteFont(headWriteFont);
// 内容的策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
// 背景绿色
contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
WriteFont contentWriteFont = new WriteFont();
// 字体大小
contentWriteFont.setFontHeightInPoints((short) 20);
contentWriteCellStyle.setWriteFont(contentWriteFont);
// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcel.write(filePath, CustomStyleData.class)
.registerWriteHandler(horizontalCellStyleStrategy)
.sheet("模板")
.doWrite(customStyleData);
}
但是一般不会搞的这么花里胡哨的,简单的功能就足够使用了