市面上大多数excel转图片为收费工具,借鉴他人用awt的Graphics2D自己实现的工具类,只涉及poi依赖。
/**
* 版权: taylor
* 描述: 将excel转为图片工具类
* 创建时间:2020年08月13日
*/
package com.excel.taylor.util;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
/**
* 〈功能简述〉将excel转为图片工具类
*
* @author Taylor
* @version [V1.0, 2020年08月13日]
* @since [XX系统]
*/
public class ExcelToImageUtil {
/**
* 将包含excel的输入流转为图片写入输出流中,支持xls及xlsx格式
* @param sheetName 表格名,可以为null,默认取第一个
* @param inputStream 输入流
* @param outputStream 输出流
* @throws RuntimeException 解析或IO异常
*/
public static void excelToImageOutput(@Nullable String sheetName, @NonNull InputStream inputStream, @NonNull OutputStream outputStream){
try (Workbook workbook = WorkbookFactory.create(inputStream)) {
Sheet sheet;
if (StringUtils.isNotBlank(sheetName)) {
sheet = workbook.getSheet(sheetName);
}else {
sheet = workbook.getSheetAt(0);
}
BufferedImage bufferedImage = ExcelToImageUtil.parseExcelToImage(sheet);
ImageIO.write(bufferedImage,"png",outputStream);
} catch (InvalidFormatException e) {
throw new RuntimeException("excel解析失败:"+e.getMessage(),e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 解析要画图的表格
* @param sheet 表格
* @return {@link BufferedImage} 可以用{@link ImageIO}来处理
*/
@NonNull
public static BufferedImage parseExcelToImage(@NonNull Sheet sheet){
//图片宽度
int imageWidth = 0;
//图片高度
int imageHeight = 0;
// 获取整个sheet中合并单元格组合的集合
List<CellRangeAddress> rangeAddress = sheet.getMergedRegions();
//根据读取数据,动态获得表边界行列
int totalRow = sheet.getLastRowNum()+1;
int totalCol = 0;
for (Row cells : sheet) {
totalCol = cells.getLastCellNum() > totalCol
? cells.getLastCellNum():totalCol;
}
//创建单元格数组,用于遍历单元格
UserCell[][] cells = new UserCell[totalRow + 1][totalCol + 1];
// 存放行边界
int[] rowPixPos = new int[totalRow + 1];
rowPixPos[0] = 0;
// 存放列边界
int[] colPixPos = new int[totalCol + 1];
colPixPos[0] = 0;
//开始遍历单元格
for (int i = 0; i < totalRow; i++) {
for (int j = 0