先要制作一个空的excel模板(也可以全由代码写成,使用excel模板的好处是,不用代码去实现复杂的排版,只需要填写内容就可),注意文件内容不能太大,否则在生成图片时可能会导致内存溢出(内容非常多的建议不要导出带图片的)。
org.apache.poi
poi
3.17
org.apache.poi
poi-ooxml
3.17
com.github.ulisesbocchio
jasypt-spring-boot-starter
3.0.3
controller层
// 导出用户购物车明细 带图片
@RequestMapping("/exportusertruckdetail")
public ResponseEntity exportUserTruckDetail(@RequestParam(value="data") String data)
{
logger.debug("ExportController.exportUserTruckDetail in, param:{}", data);
try {
JSONObject json = JSON.parseObject(data);
String userId = json.getString("userId");
Date startDate = json.getDate("startDate");
Date endDate = json.getDate("endDate");
String companyId = json.getString("companyId");
boolean picFlag = json.getBooleanValue("picFlag");
File excel = exportService.exportUserTruckDetail(companyId, userId, startDate, endDate, picFlag);
return HttpUtils.export(excel);
} catch (Exception e) {
logger.error("errorCode : filemanage_exportusertruckdetail_sys, errorMessages : 导出用户购物车明细异常!", e);
return HttpUtils.exportFailed(e.getMessage());
}
}
// HttpUtils.export
public static ResponseEntity export(File file) {
if (file == null) {
return null;
} else {
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition", "attachment; filename=" + file.getName());
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
headers.add("Last-Modified", (new Date()).toString());
headers.add("ETag", String.valueOf(System.currentTimeMillis()));
return ((BodyBuilder)ResponseEntity.ok().headers(headers)).contentLength(file.length()).contentType(MediaType.parseMediaType("application/octet-stream")).body(new FileSystemResource(file));
}
}
// HttpUtils.exportFailed
public static ResponseEntity exportFailed(String message) {
InputStream ins = new ByteArrayInputStream(message.getBytes());
return ResponseEntity.ok().contentType(MediaType.parseMediaType("application/json;charset=UTF-8")).body(new InputStreamResource(ins));
}
service层
@Override
public File exportUserTruckDetail(String companyId, String userId, Date startDate, Date endDate, boolean picFlag) throws Exception {
List
ExcelUtil.insertExcelPic
/**
* <一句话功能简述> excel插入图片
* <功能详细描述>
* author: zhanggw
* 创建时间: 2022/5/25
* @param book poi book对象
* @param drawingPatriarch 用于图片插入Represents a SpreadsheetML drawing
* @param rowIndex 图片插入的单元格第几行
* @param colIndex 图片插入的单元格第几列
* @param localPicPath 本地图片路径
*/
public static void insertExcelPic(XSSFWorkbook book, XSSFDrawing drawingPatriarch, int rowIndex, int colIndex, String localPicPath) throws IOException {
// 获取图片后缀格式
String fileSuffix = localPicPath.substring(localPicPath.lastIndexOf(".") + 1);
fileSuffix = fileSuffix.toLowerCase();
// 将图片写入到字节数组输出流中
BufferedImage bufferImg;
ByteArrayOutputStream picByteOut = new ByteArrayOutputStream();
bufferImg = ImageIO.read(new File(localPicPath));
ImageIO.write(bufferImg, fileSuffix, picByteOut);
// 将图片字节数组输出流写入到excel中
XSSFClientAnchor anchor = new XSSFClientAnchor(12, 3, 0, 0,
(short) colIndex, rowIndex, (short) colIndex + 1, rowIndex + 1);
anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
drawingPatriarch.createPicture(anchor, book.addPicture(picByteOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
picByteOut.close();
}
ExcelUtil.downloadPic
public static boolean downloadPic(String httpUrlPath, String localPath, boolean forceDownload){
try{
logger.trace("开始下载文件{}到{}", httpUrlPath, localPath);
String suffix = localPath.substring(localPath.lastIndexOf(".")+1);
if(suffix.equalsIgnoreCase("jpg") || suffix.equalsIgnoreCase("png")){
if(FileUtil.isExist(localPath)){
if(forceDownload){
new File(localPath).delete();
}else{
logger.trace("{}图片缓存,不下载!", localPath);
return true;
}
}
boolean ret = FileUtil.download(httpUrlPath, localPath);
if(ret){
logger.trace("下载文件{}到{}成功", httpUrlPath, localPath);
return true;
}else{
logger.debug("下载文件{}到{}失败", httpUrlPath, localPath);
}
}
}catch (Exception e){
logger.error("下载图片异常"+httpUrlPath, e);
}
return false;
}
// 通过url下载图片保存到本地
public static boolean download(String urlString, String localPath) {
try{
// 构造URL
URL url = new URL(urlString);
// 打开连接
URLConnection con = url.openConnection();
// 输入流
InputStream is = con.getInputStream();
// 1K的数据缓冲
byte[] bs = new byte[1024];
// 读取到的数据长度
int len;
// 输出的文件流
File file = new File(localPath);
FileOutputStream os = new FileOutputStream(file, true);
// 开始读取
while ((len = is.read(bs)) != -1) {
os.write(bs, 0, len);
}
// 完毕,关闭所有链接
os.close();
is.close();
return true;
}catch (Exception e){
logger.error("下载图片到本地异常!", e);
}
return false;
}