java 向word中添加excel附件并向excel单元格中加入图片并压缩图片并根据图片动态控制单元格高度宽度

时间:2025-02-07 16:45:42
import com.ruoyi.common.utils.DownLoadFileUtil; import com.ruoyi.common.utils.minio.MinioUtil; import com.ruoyi.common.utils.poi.CompressImageUtil; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.system.domain.BBuildingDict; import com.ruoyi.system.domain.ImgFile; import com.ruoyi.system.domain.TShop; import com.ruoyi.system.domain.vo.BManageDTO; import com.ruoyi.system.domain.vo.BManageVo; import com.ruoyi.system.domain.vo.TShopCheckInfoVo; import com.ruoyi.system.mapper.BBuildingDictMapper; import com.ruoyi.system.mapper.BManageMapper; import com.ruoyi.system.mapper.TShopMapper; import com.ruoyi.system.service.ImgExcelService; import io.minio.PutObjectArgs; import jxl.Workbook; import jxl.format.Colour; import jxl.format.UnderlineStyle; import jxl.write.*; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.*; import java.lang.Boolean; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.stream.Collectors; /** * word附件导出 */ @ResponseBody @RequestMapping(value = "/generateReports", method = RequestMethod.GET) public void generateReports(HttpServletRequest request, HttpServletResponse response) throws Exception { //查询数据 Map condition = getSelection(request); //生成excel Long num = System.currentTimeMillis(); String filename = num + ".xls"; sendExcel(request, response, filename); //制作word WordUtil wordUtil = new WordUtil(); Map<String, Object> dataMap = new HashMap<String, Object>(); /**wordTemplate*/ Department dept = (Department) request.getSession().getAttribute("CURRENT_DEPT"); // List<Map> mapList = sortingService.findShopInfoBySort2(condition); // if (() > 0) { //向word中添加数据map Date startTime = DateUtil.parseTime(start); Date endTime = DateUtil.parseTime(end); String startTime1 = new SimpleDateFormat("yyyy年MM月dd日").format(startTime); String endTime1 = new SimpleDateFormat("yyyy年MM月dd日").format(endTime); dataMap.put("startTime", startTime1); dataMap.put("endTime", endTime1); // } //调试 // (1000); // ("excelEnclosure", (filePath + "副本" + filename)); //写入 try { response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/msword"); response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("函告" + num + ".doc", "UTF-8")); } catch (Exception ex) { ex.printStackTrace(); } wordUtil.createDoc(dataMap, response, "wordTemplate", filePath + "函告" + num + ".doc"); //删除临时文件 File file = new File(filePath + "副本" + filename); if (file.exists()) { file.delete(); } } public class WordUtil { public Configuration configure=null; public WordUtil(){ // configure=new Configuration(Configuration.VERSION_2_3_22); configure=new Configuration(); configure.setDefaultEncoding("utf-8"); } //创建word public void createDoc( Map<String,Object> dataMap,HttpServletResponse response, String downloadType, String savePath){ try { //加载需要装填的模板 Template template=null; //设置模板装置方法和路径,FreeMarker支持多种模板装载方法。可以从servlet,classpath,数据库装载。 //加载模板文件,放在template下 configure.setClassForTemplateLoading(this.getClass(), "/com/~/util/template"); //设置对象包装器 //(new DefaultObjectWrapper()); //设置异常处理器 configure.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER); //定义Template对象,注意模板类型名字与downloadType要一致 template=configure.getTemplate(downloadType + ".xml"); File outFile=new File(savePath); Writer out=null; //指定编码表需使用转换流,转换流对象要接收一个字节输出流 out = response.getWriter(); template.process(dataMap, out); out.close(); } catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); } } } /** * 制作excel */ public void sendExcel(HttpServletRequest request, HttpServletResponse response, String filename) { //condition 筛选条件 Map condition = getSelection(request); //获取数据 List<TShopCheckInfo> list = this.tShopCheckInfoService.selectShopInfoList(condition); //列头 String[] title = { "是否", "图片",}; String sheetName = "sheet1"; String[][] content = new String[list.size()][2]; try { int nu = 50; if (list.size() < nu) { nu = list.size(); } //循环添加数据 数据库存的图片地址 for (int i = 0; i < list.size(); i++) { content[i][0] = list.get(i).getEscape() ? (StringUtils.isNotEmpty(list.get(i).getEscapeText()) ? "是(" + list.get(i).getEscapeText() + ")" : "是") : "否"; content[i][1] = list.get(i).getEscapeImgs(); } } catch (Exception e) { e.printStackTrace(); } HSSFWorkbook wb = ExcelUtil.getHSSFWorkbook(sheetName, title, content, null); try { // TODO: 2020/7/29 地址需要更换 //输出Excel文件 // 这里是先将文件输出到服务器本地,再用WritableWorkbook进行图片处理 FileOutputStream output = new FileOutputStream(filePath + filename); wb.write(output); output.flush(); //测试 Thread.sleep(1000); //插入图片到excel List<String> nameList = new ArrayList<>(); excelImgUpdate(filePath, filename, list, nameList); //响应到客户端 // FileInputStream inputStream = new FileInputStream(filePath + "副本" + filename); // workbook = (inputStream); //setHeader // downLoadExcel("附件" + filename, response, workbook); // FileOutputStream output = new FileOutputStream(filePath + filename); //删除临时文件 // (filePath + "副本" + filename); nameList.add(filePath + filename); delTemporary(nameList); } catch (Exception e) { e.printStackTrace(); } } package com.ztwx.ezxf.util; import org.apache.commons.lang.StringUtils; import org.apache.poi.hssf.usermodel.*; public class ExcelUtil { /** * 导出Excel */ public static HSSFWorkbook getHSSFWorkbook(String sheetName, String[] title, String[][] values, HSSFWorkbook wb) { // 第一步,创建一个HSSFWorkbook,对应一个Excel文件 if (wb == null) wb = new HSSFWorkbook(); // 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet HSSFSheet sheet = wb.createSheet(sheetName); //设置单元格的宽度 sheet.setDefaultColumnWidth(18); //设置第一列宽度 sheet.setColumnWidth(0, 252*40+323); //设置第四列宽度 sheet.setColumnWidth(3, 252*25+323); // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制 HSSFRow row = sheet.createRow(0); // 第四步,创建单元格,并设置值表头 设置表头居中 HSSFCellStyle style = wb.createCellStyle(); style.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框 style.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框 style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框 style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框 style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式 style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中 //声明列对象 HSSFCell cell = null; HSSFCell cell2 = null; HSSFFont font = wb.createFont(); //创建标题 for (int i = 0; i < title.length; i++) { cell = row.createCell(i); cell.setCellValue(title[i]); //字体 // (Font.BOLDWEIGHT_BOLD); font.setFontHeightInPoints((short) 12); style.setFont(font); cell.setCellStyle(style); } //创建内容 for (int i = 0; i < values.length; i++) { row = sheet.createRow(i + 1); //清空字体 // ((short)400); // (false); // (font); for (int j = 0; j < values[i].length; j++) { //将内容按顺序赋给对应的列对象 cell2 = row.createCell(j); if(StringUtils.isNotBlank(values[i][j])){ cell2.setCellValue(values[i][j]); }else{ cell2.setCellValue("/"); } // 内容设置样式 cell2.setCellStyle(style); } } return wb; } } //向excel 加入图片 public List<String> excelImgUpdate(String filePath, String filename, List<TShopCheckInfo> list, List<String> nameList) throws Exception { Workbook wb = Workbook.getWorkbook(new File(filePath + filename)); // 获得原始文档 //创建副本; WritableWorkbook workbook = Workbook.createWorkbook(new File(filePath + "副本" + filename), wb); WritableSheet sheet = workbook.getSheet(0); //调用图片插入函数 图片插入的行列 //用map存放有图片时候对应的行信息 列固定 // Map<Integer, ArrayList> map = new HashMap(); for (int i = 0; i < list.size(); i++) { //8 插入对应的列 String json9 = list.get(i).getEscapeImgs(); ArrayList arrayList9 = getImgSrc(json9); if (arrayList9.size() > 0) { nameList = imgExcelService.addPictureToExcel(nameList, sheet, arrayList9, i + 1, 8); } } //写入Excel表格中; workbook.write(); //关闭流; workbook.close(); return nameList; } //图片压缩与写入 单元格控制 public List<String> addPictureToExcel(List<String> nameList,WritableSheet picSheet, ArrayList pictureFilePaths, double cellRow, double cellCol) throws Exception { final double cellSpace = 0.02;//图片之间的间隔 占比 double picWidthMax = 0; double picHeightSum = 0;//空出图片 离上下边框的距离 ImgFile[] imgFiles = new ImgFile[pictureFilePaths.size()]; //存放临时文件名 for (int i = 0; i < pictureFilePaths.size(); i++) { ImgFile imgFile = new ImgFile(); //下载图片到本地 Long da = System.currentTimeMillis(); // String filePath = (); String path = filePath + da + ".jpg"; nameList.add(path); downloadPicture(pictureFilePaths.get(i).toString(), path); //图片压缩 // (path).size(300,300).toFile(path); CompressImageUtil.reduceImg(path,path,0,0,0.5f); File imageFile = new File(path); // 读入图片 BufferedImage picImage = ImageIO.read(imageFile); ByteArrayOutputStream pngByteArray = new ByteArrayOutputStream(); //将其他图片格式写成png的形式 ImageIO.write(picImage, "PNG", pngByteArray); imgFile.setPngByteArray(pngByteArray); // 取得图片的像素高度,宽度 //这里设置图片在单元格的尺寸 原理不清楚 该值为具体实验值 double picWidth = picImage.getWidth() * 0.06; // double picWidth = () ; double picHeight = picImage.getHeight() * 7; // double picHeight = () ; imgFile.setHeigth(picHeight); imgFile.setWidth(picWidth); //汇总 if (picWidth > picWidthMax) { picWidthMax = picWidth; } picHeightSum += picHeight; imgFiles[i] = imgFile; } WritableFont font = new WritableFont(WritableFont.ARIAL, 14, WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.RED); WritableCellFormat cellFormat = new WritableCellFormat(font); //设置背景颜色; cellFormat.setBackground(Colour.WHITE); //设置边框; cellFormat.setBorder(Border.ALL, BorderLineStyle.THIN); //设置自动换行; cellFormat.setWrap(true); //设置文字居中对齐方式; cellFormat.setAlignment(Alignment.CENTRE); //设置垂直居中; cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE); Label imageLabel = new Label((int) cellCol, (int) cellRow, "", cellFormat); picSheet.addCell(imageLabel); //获取图片需要插入的单元格 // WritableCell cell =(0, 0); //设置单元格宽高 picSheet.setColumnView((int) cellCol, (int) picWidthMax);//列宽 picSheet.setRowView((int) cellRow, (int) picHeightSum);//行高 double widthStart = cellSpace;//开始宽度 double heightStart = cellSpace;//开始高度 //插入图片 for (ImgFile imgFile0 : imgFiles) { double heigthFact = imgFile0.getHeigth() / picHeightSum;//实际高度 double widthFact = imgFile0.getWidth() / picWidthMax; //图片高度压缩了cellSpace+moreHeight,目的是为了该图片高度不超出单元格 if (heightStart + heigthFact >= 1) { double moreHeight = heightStart + heigthFact - 1.00; heigthFact -= moreHeight; heigthFact -= cellSpace; } //图片宽度压缩了cellSpace,目的是为了该图片宽度不超出单元格 if (widthFact >= 1) { widthFact -= cellSpace; } //生成图片对象 WritableImage image = new WritableImage(cellCol + widthStart, cellRow + heightStart, widthFact, heigthFact, imgFile0.getPngByteArray().toByteArray()); //将图片对象插入到sheet picSheet.addImage(image); //开始高度累加,获取下一张图片的起始高度(相对该单元格) heightStart += heigthFact; heightStart += cellSpace;//图片直接间隔为cellSpace } return nameList; } private static void downloadPicture(String urlList, String path) { URL url = null; try { url = new URL(urlList); DataInputStream dataInputStream = new DataInputStream(url.openStream()); FileOutputStream fileOutputStream = new FileOutputStream(new File(path)); ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length; while ((length = dataInputStream.read(buffer)) > 0) { output.write(buffer, 0, length); } BASE64Encoder encoder = new BASE64Encoder(); String encode = encoder.encode(buffer);//返回Base64编码过的字节数组字符串 System.out.println(encode); fileOutputStream.write(output.toByteArray()); dataInputStream.close(); fileOutputStream.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }