当前位置:网站首页>easypoi导出表格带echars图表
easypoi导出表格带echars图表
2022-07-28 05:29:00 【符华-】
效果

实现思路
前端图表用的是echars显示,只需要让前端将图表以图片的形式,将图片的base64传过来,后端接收到这个base64,写入到工作簿中的sheet中即可。无论是折线图、饼图、柱状图都是一样的,以图片的形式将图片追加到sheet中,只需要设定好图表的偏移量即可。
实现
1、ExcelStyleUtil 导出样式工具类
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.entity.params.ExcelForEachParams;
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
import org.apache.poi.ss.usermodel.*;
public class ExcelStyleUtil implements IExcelExportStyler {
private static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT");
private static final short FONT_SIZE_TEN = 12;
private static final short FONT_SIZE_ELEVEN = 14;
private static final short FONT_SIZE_TWELVE = 18;
/** * 大标题样式 */
private CellStyle headerStyle;
/** * 每列标题样式 */
private CellStyle titleStyle;
/** * 数据行样式 */
private CellStyle styles;
public ExcelStyleUtil(Workbook workbook) {
this.init(workbook);
}
/** * 初始化样式 * @param workbook */
private void init(Workbook workbook) {
this.headerStyle = initHeaderStyle(workbook);
this.titleStyle = initTitleStyle(workbook,true,FONT_SIZE_ELEVEN);
this.styles = initStyles(workbook);
}
@Override
public CellStyle getHeaderStyle(short i) {
return headerStyle;
}
@Override
public CellStyle getTitleStyle(short i) {
return titleStyle;
}
@Override
public CellStyle getTemplateStyles(boolean b, ExcelForEachParams excelForEachParams) {
return null;
}
@Override
public CellStyle getStyles(boolean b, ExcelExportEntity excelExportEntity) {
return styles;
}
@Override
public CellStyle getStyles(Cell cell, int i, ExcelExportEntity entity, Object o, Object o1) {
return getStyles(true, entity);
}
/** * 设置隔行背景色 */
public static CellStyle getStyles(Workbook workbook,boolean isBold,short size) {
CellStyle style = initTitleStyle(workbook,isBold,size);
style.setDataFormat(STRING_FORMAT);
return style;
}
/** * 初始化--大标题样式 */
private static CellStyle initHeaderStyle(Workbook workbook) {
CellStyle style = getBaseCellStyle(workbook);
style.setFont(getFont(workbook, FONT_SIZE_TWELVE, true));
return style;
}
/** * 初始化--每列标题样式 */
private static CellStyle initTitleStyle(Workbook workbook,boolean isBold,short size) {
CellStyle style = getBaseCellStyle(workbook);
style.setFont(getFont(workbook, size, isBold));
//背景色
style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
return style;
}
/** * 初始化--数据行样式 */
private static CellStyle initStyles(Workbook workbook) {
CellStyle style = getBaseCellStyle(workbook);
style.setFont(getFont(workbook, FONT_SIZE_TEN, false));
style.setDataFormat(STRING_FORMAT);
return style;
}
/** * 基础样式 */
private static CellStyle getBaseCellStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
//下边框
style.setBorderBottom(BorderStyle.THIN);
//左边框
style.setBorderLeft(BorderStyle.THIN);
//上边框
style.setBorderTop(BorderStyle.THIN);
//右边框
style.setBorderRight(BorderStyle.THIN);
//水平居中
style.setAlignment(HorizontalAlignment.CENTER);
//上下居中
style.setVerticalAlignment(VerticalAlignment.CENTER);
//设置自动换行
style.setWrapText(true);
return style;
}
/** * 字体样式 * @param size 字体大小 * @param isBold 是否加粗 */
private static Font getFont(Workbook workbook, short size, boolean isBold) {
Font font = workbook.createFont();
//字体样式
font.setFontName("宋体");
//是否加粗
font.setBold(isBold);
//字体大小
font.setFontHeightInPoints(size);
return font;
}
}
2、ExcelUtil 导出工具类
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.afterturn.easypoi.excel.imports.ExcelImportService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.*;
public class ExcelUtil {
/** * excel 导出 * @param list 数据 * @param title 标题 * @param sheetName sheet名称 * @param pojoClass pojo类型 * @param fileName 文件名称 */
public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response){
ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.XSSF);
exportParams.setStyle(ExcelStyleUtil.class);
defaultExport(list, pojoClass, fileName, response, exportParams);
}
/** * excel 导出 * @param list 数据 * @param pojoClass pojo类型 * @param fileName 文件名称 */
public static void exportExcel(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response){
ExportParams exportParams = new ExportParams();
exportParams.setStyle(ExcelStyleUtil.class);
defaultExport(list, pojoClass, fileName, response, exportParams);
}
/** * list map 导出 * @param list 数据 * @param fileName 文件名称 */
public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response){
ExportParams exportParams = new ExportParams();
exportParams.setStyle(ExcelStyleUtil.class);
defaultExport(list, fileName, response);
}
/** * 默认的 excel 导出 * @param list 数据 * @param pojoClass pojo类型 * @param fileName 文件名称 * @param exportParams 导出参数 */
private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams){
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
downLoadExcel(fileName, response, workbook);
}
/** * 默认的 excel 导出 * @param list 数据 * @param fileName 文件名称 */
private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response){
Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.XSSF);
downLoadExcel(fileName, response, workbook);
}
/** * 下载 * @param fileName 文件名称 * @param response * @param workbook excel数据 */
public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook){
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + "." + ExcelTypeEnum.XLS.getValue(), "UTF-8"));
workbook.write(response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
/** * excel 导入 * @param filePath excel文件路径 * @param titleRows 标题行 * @param headerRows 表头行 * @param pojoClass pojo类型 */
public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
if (StringUtils.isBlank(filePath)) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
params.setNeedSave(true);
params.setSaveUrl("/excel/");
try {
return ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
} catch (NoSuchElementException e) {
throw new IOException("模板不能为空");
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
/** * excel 导入 * @param file 上传的文件 * @param titleRows 标题行 * @param headerRows 表头行 * @param needVerify 是否检验excel内容 * @param pojoClass pojo类型 */
public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, boolean needVerify, Class<T> pojoClass) throws IOException {
if (file == null) {
return null;
}
try {
return importExcel(file.getInputStream(), titleRows, headerRows, needVerify, pojoClass);
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
/** * excel 导入 * @param inputStream 文件输入流 * @param titleRows 标题行 * @param headerRows 表头行 * @param needVerify 是否检验excel内容 * @param pojoClass pojo类型 */
public static <T> List<T> importExcel(InputStream inputStream, Integer titleRows, Integer headerRows, boolean needVerify, Class<T> pojoClass) throws IOException {
if (inputStream == null) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
params.setSaveUrl("upload/excel/");
params.setNeedSave(true);
params.setNeedVerify(needVerify);
try {
return ExcelImportUtil.importExcel(inputStream, pojoClass, params);
} catch (NoSuchElementException e) {
throw new IOException("excel文件不能为空");
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
/** * Excel 类型枚举 */
enum ExcelTypeEnum {
XLS("xls"), XLSX("xlsx");
private String value;
ExcelTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
/** * 上传文件,返回一个workbook * @param file */
public static Workbook importExcel(MultipartFile file) throws IOException {
File toFile = new File(file.getOriginalFilename());
Workbook workbook = null;
if(toFile.getPath().endsWith("xls")){
workbook = new HSSFWorkbook(file.getInputStream());
}else if(toFile.getPath().endsWith("xlsx")){
workbook = new XSSFWorkbook(file.getInputStream());
}else {
throw new RuntimeException("请确认你上传的文件类型");
}
return workbook;
}
/** * 读取指定sheet的数据 * @param file 上传的文件 * @param sheetName 要读取的sheetName * @param titleRows 表头行数 * @param headRows 标题行数 * @param startRows 表头之前有多少行不要的数据,从1开始,忽略空行 * @param readRows 要读取多少行数据,从0开始,比如读取十行,值就是9; 不指定时默认为0 * @param pojoClass 实体 */
public static <T> List<T> importExcel(MultipartFile file,String sheetName,Integer titleRows,Integer headRows, Integer startRows,Integer readRows,Class<T> pojoClass) throws Exception {
Workbook workbook = importExcel(file);
int numberOfSheets = workbook.getNumberOfSheets();
List<T> list = null;
for (int i = 0; i < numberOfSheets; i++) {
String name = workbook.getSheetName(i).trim();
if (name.equals(sheetName) || name.endsWith(sheetName)){
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headRows);
params.setStartRows(startRows);
params.setReadRows(readRows);
//第几个sheet页
params.setStartSheetIndex(i);
final ExcelImportService excelImportService = new ExcelImportService();
ExcelImportResult<T> result = excelImportService.importExcelByIs(file.getInputStream(), pojoClass, params, false);
list = result.getList();
break;
}
}
return list;
}
/** * 导出Excel,并在最后追加图片 * @param sheetName sheet名称 * @param wb Workbook对象 * @param imgUrl 图片的base64字符串 */
public static Workbook getWorkbook(String sheetName,Workbook wb, String imgUrl) throws IOException {
if (wb == null) {
wb = new HSSFWorkbook();
}
// 在workbook中根据sheet名称获取指定的sheet
Sheet sheet = wb.getSheet(sheetName);
/*生成图表*/
if(!StringUtils.isEmpty(imgUrl)) {
//拆分base64编码后部分
String[] imgUrlArr = imgUrl.split("base64,");
byte[] buffer = new BASE64Decoder().decodeBuffer(imgUrlArr[1]);
//图片临时存放地址
String picPath = System.getProperty("user.dir")+"\\upload\\image\\pic.png";
//图片文件
File file = new File(picPath);
try {
//生成图片
OutputStream out = new FileOutputStream(file);//图片输出流
out.write(buffer);
out.flush();//清空流
out.close();//关闭流
// 将图片写入流中
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
BufferedImage bufferImg = ImageIO.read(new File(picPath));
ImageIO.write(bufferImg, "PNG", outStream);
// 利用Drawing将图片写入EXCEL
Drawing<?> drawing = sheet.createDrawingPatriarch();
//设置图表偏移量:第1个单元格中x轴的偏移量、第1个单元格中y轴的偏移量、 第2个单元格中x轴的偏移量、 第2个单元格中y轴的偏移量、第1个单元格的列号、第1个单元格的行号、 第2个单元格的列号、第2个单元格的行号
//HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) 0, 6, (short) 9, 40);
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 6, 9, 40);
drawing.createPicture(anchor, wb.addPicture(outStream.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG));
} catch (Exception ex) {
ex.printStackTrace();
}
if (file.exists()) {
file.delete();//删除图片
}
}
return wb;
}
}
3、controller
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.common.util.ExcelStyleUtil;
import com.common.util.ExcelUtil;
import lombok.Data;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/test")
public class TestController {
@Data
public static class Test{
@Excel(name = "名称",width = 25)
private String name;
@Excel(name = "1月",width = 15)
private Double m1;
@Excel(name = "2月",width = 15)
private Double m2;
@Excel(name = "3月",width = 15)
private Double m3;
@Excel(name = "4月",width = 15)
private Double m4;
@Excel(name = "5月",width = 15)
private Double m5;
@Excel(name = "6月",width = 15)
private Double m6;
@Excel(name = "7月",width = 15)
private Double m7;
@Excel(name = "8月",width = 15)
private Double m8;
@Excel(name = "9月",width = 15)
private Double m9;
@Excel(name = "10月",width = 15)
private Double m10;
@Excel(name = "11月",width = 15)
private Double m11;
@Excel(name = "12月",width = 15)
private Double m12;
public Test(String name, Double m1, Double m2, Double m3, Double m4, Double m5, Double m6, Double m7, Double m8, Double m9, Double m10, Double m11, Double m12) {
this.name = name;
this.m1 = m1;
this.m2 = m2;
this.m3 = m3;
this.m4 = m4;
this.m5 = m5;
this.m6 = m6;
this.m7 = m7;
this.m8 = m8;
this.m9 = m9;
this.m10 = m10;
this.m11 = m11;
this.m12 = m12;
}
}
@PostMapping("/export")
public void export(String imgUrl, HttpServletResponse response) throws IOException {
List<Test> list = new ArrayList<>();
list.add(new Test("工业",885.0,845.0,832.0,878.0,996.0,763.0,820.0,848.0,798.0,925.0,933.0,777.96));
list.add(new Test("农业",224.32,177.0,141.75,231.23,254.22,300.25,244.32,177.88,123.0,280.88,235.74,333.0));
list.add(new Test("商业",650.36,622.25,672.47,599.0,548.0,621.36,647.14,420.25,752.98,600.75,567.1,643.0));
list.add(new Test("其他",444.3,486.0,421.24,431.22,333.1,420.28,398.74,385.57,324.0,420.75,421.12,468.0));
ExportParams params = new ExportParams();
params.setTitle("年电量统计");
params.setTitleHeight((short) 15);
params.setHeight((short) 12);
params.setStyle(ExcelStyleUtil.class);
params.setSheetName("电量统计");
Workbook workbook = ExcelExportUtil.exportExcel(params,Test.class, list);
workbook = ExcelUtil.getWorkbook("电量统计", workbook, imgUrl);
ExcelUtil.downLoadExcel("年电量统计",response,workbook);
}
}
边栏推荐
- 视频格式基础知识:让你了解MKV、MP4、H.265、码率、色深等等
- PXE无人值守安装管理
- DOM - Events
- As a result, fill in the birthday candles
- [learning notes] thread creation
- DOM -- page rendering, style attribute operation, preloading and lazy loading, anti shake and throttling
- DNS域名解析
- Esxi community network card driver
- Vmware workstation configuration net mode
- 关于正则的教程
猜你喜欢

MOOC Weng Kai C language week 7: array operation: 1. array operation 2. Search 3. preliminary sorting

PXE无人值守安装管理

Vmware workstation configuration net mode

Results fill in the blank shopping list (teach you to solve it with Excel)

MOOC Weng Kai C language week 6: arrays and functions: 1. Arrays 2. Definition and use of functions 3. Parameters and variables of functions 4. Two dimensional arrays

Svg understanding and drawing application

Neo4j运行报错Error occurred during initialization of VM Incompatible minimum and maximum heap sizes spec

On cookies and session

Custom components -- styles

Applets: WSX scripts
随机推荐
Wangeditor (@4.7.15) - lightweight rich text editor
[learning notes] coding ability
Technology sharing | how to do Assertion Verification in interface automated testing?
Neo4j运行报错Error occurred during initialization of VM Incompatible minimum and maximum heap sizes spec
Results fill in the blank shopping list (teach you to solve it with Excel)
Results fill in the blanks carelessly (violent solution)
关于正则的教程
DOM -- event chain, event bubble and capture, event proxy
Applets: lifecycle
Principle and configuration of NAT and pat
Network - transport layer (detailed version)
My deployment notes
MOOC翁恺 C语言 第三周:判断与循环:1.判断
bond模式配置
[learning notes] process creation
Joern的代码使用-devign
Media set up live broadcast server
NAT-网络地址转换
Life cycle (process) of software testing
Blue bridge code error ticket