电子公章印章在线制作网站,重庆网约车,商城类网站建设费用,郑州网站建设开发本文假定 Excel 文件中保存的是员工数据#xff0c;并且数据中带有员工的头像。代码支持的图片格式有png、bmp、jpg、gif。但是这里需要注意#xff0c;有些网站上下载的图片虽然后缀名是 jpg#xff0c;但是文件二进制内容的格式是 WebP 的。Java8 目前官方api不支持 WebP …本文假定 Excel 文件中保存的是员工数据并且数据中带有员工的头像。代码支持的图片格式有png、bmp、jpg、gif。但是这里需要注意有些网站上下载的图片虽然后缀名是 jpg但是文件二进制内容的格式是 WebP 的。Java8 目前官方api不支持 WebP 本文不涉及webp相关话题本文代码也不支持 WebP 格式。
另外我还遇到个坑POI 5.2.5 在处理部分 jpg 格式图片的时候无法把图片输出到 Excel 文件。为了解决这个问题我在代码中把所有图片强行转成 png保存为硬盘上的临时文件再重新输出到 Excel 文件中。这个问题我没有在 POI 4.1.2 版本遇到过。
POI 的接口是线程不安全的多个线程同时向一个文件输出会造成错误。如果读者想要在多线程环境比如网站后端使用下面的代码要么使用锁要么确保各个线程输出不同的文件。
本文的代码计算了图片的缩放比例并且使用 picture.resize(scaleX, scaleY); 方法来设置图片缩放比例。这也与 POI 4.1.2 版本不同。POI 4.1.2 版本使用 picture.resize(1, 1); 会自动缩放图片调整成合适大小。
员工的 DTO 类 /*** 员工DTO*/
public class EmployeeDTO {// 工号private String no;// 姓名private String name;// 性别private String gender;// 头像private String portrait;Overridepublic String toString() {final StringBuffer sb new StringBuffer(Employee{);sb.append(no).append(no).append(\);sb.append(, name).append(name).append(\);sb.append(, gender).append(gender).append(\);sb.append(, portrait).append(portrait).append(\);sb.append(});return sb.toString();}public String getNo() {return no;}public void setNo(String no) {this.no no;}public String getName() {return name;}public void setName(String name) {this.name name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender gender;}public String getPortrait() {return portrait;}public void setPortrait(String portrait) {this.portrait portrait;}
}
用来生成Excel 文件的 ImageExcelUtils 类 import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;import javax.imageio.ImageIO;public class ImageExcelUtils {/*** 读取jpg图片* param path 图片文件路径* return BufferedImage*/public static BufferedImage readBufferedImage(String path) {BufferedImage originImage null;BufferedImage result null;try {File file new File(path);originImage ImageIO.read(file);// 确保图片颜色只有RGB没有alpha透明度result new BufferedImage(originImage.getWidth(),originImage.getHeight(),BufferedImage.TYPE_INT_RGB);result.getGraphics().drawImage(originImage, 0, 0, null);} catch (IOException e) {e.printStackTrace();}return result;}/*** 设置excel文件的图片* param workbook 工作簿* param sheet sheet页* param imgFilePath 图片文件路径* param row1 图片起始的行* param col1 图片起始的列* param tempFilePath 临时文件路径*/public static void setExcelImg(Workbook workbook, Sheet sheet, String imgFilePath,int row1, int col1, int width, int height, String tempFilePath) {File file new File(imgFilePath);if (!file.exists()) {return;}// 临时文件File tempFile new File(tempFilePath);if (tempFile.exists()) {tempFile.delete();}FileInputStream inputStream null;boolean isClose false;try {BufferedImage bufferedImage readBufferedImage(imgFilePath);int imageWidth bufferedImage.getWidth();int imageHeight bufferedImage.getHeight();ImageIO.write(bufferedImage, png, tempFile);inputStream new FileInputStream(tempFile);//利用POI提供的工具类把文件流转化成二进制数据byte[] bytes IOUtils.toByteArray(inputStream);//向POI内存中添加一张图片返回图片在图片集合中的索引int pictureIndex workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);//参数一图片的二进制数据参数二图片类型//从Workbook中得到绘制图片的工具类CreationHelper helper workbook.getCreationHelper();//创建锚点设置图片坐标ClientAnchor clientAnchor helper.createClientAnchor();clientAnchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);clientAnchor.setRow1(row1); // 设置起始行clientAnchor.setCol1(col1); // 设置起始列//从sheet对象中得到一个绘图对象Drawing? drawingPatriarch sheet.createDrawingPatriarch();//绘制图片锚点图片在内存中的位置Picture picture drawingPatriarch.createPicture(clientAnchor, pictureIndex);// 使用固定的长宽比例系数double scaleX 1.0;double scaleY 1.0;if (imageWidth width imageHeight height) {scaleX 1.0;scaleY 1.0;} else {scaleX (double) width / (double) imageWidth;scaleY (double) height / (double) imageHeight;double min Math.min(scaleX, scaleY);scaleX scaleY min;}picture.resize(scaleX, scaleY);//自适应渲染图片} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if (inputStream ! null !isClose) {inputStream.close();}tempFile.delete();} catch (IOException e) {e.printStackTrace();}}}/*** 创建Excel文件* param employeeDTOList 员工列表* param file 输出的 Excel 文件* param tempFilePath 临时文件路径*/public static void createExcelFile(ListEmployeeDTO employeeDTOList, File file, String tempFilePath) {//创建工作簿excel2007版本的如果是excel2003的话。创建的对象是HSSFWorkbookWorkbook workbook new SXSSFWorkbook();//创建sheetSheet sheet workbook.createSheet(picture sheet);// 列宽分别是25个字符和40个字符一字符等于 6.107 像素sheet.setColumnWidth(0, 25 * 256);sheet.setColumnWidth(1, 25 * 256);sheet.setColumnWidth(2, 25 * 256);sheet.setColumnWidth(3, 40 * 256);// 行高是 120 磅1磅是 1.34039 像素sheet.setDefaultRowHeightInPoints(120f);// 设置字体黑体Font font workbook.createFont();font.setFontName(黑体);// 字体加粗font.setBold(true);CellStyle cellStyle workbook.createCellStyle();cellStyle.setFont(font);cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);cellStyle.setAlignment(HorizontalAlignment.CENTER);// 表格标题行Row firstRow sheet.createRow(0);Cell r0c0 firstRow.createCell(0);r0c0.setCellValue(工号);Cell r0c1 firstRow.createCell(1);r0c1.setCellValue(姓名);Cell r0c2 firstRow.createCell(2);r0c2.setCellValue(性别);Cell r0c3 firstRow.createCell(3);r0c3.setCellValue(头像);r0c0.setCellStyle(cellStyle);r0c1.setCellStyle(cellStyle);r0c2.setCellStyle(cellStyle);r0c3.setCellStyle(cellStyle);int size employeeDTOList.size();for (int i 0; i size; i) {EmployeeDTO dto employeeDTOList.get(i);int rowIndex i 1;Row row sheet.createRow(rowIndex);Cell c0 row.createCell(0);Cell c1 row.createCell(1);Cell c2 row.createCell(2);Cell c3 row.createCell(3);// 向excel中输入图片String portrait dto.getPortrait();if (null ! portrait portrait.trim().length() 0) {portrait portrait.trim();setExcelImg(workbook, sheet, portrait, rowIndex, 3, 244, 160, tempFilePath);}c0.setCellValue(dto.getNo());c1.setCellValue(dto.getName());c2.setCellValue(dto.getGender());}//创建文件输入流FileOutputStream out null;//创建文件输出流try {out new FileOutputStream(file);//调用工作簿的write创建excelworkbook.write(out);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if (out ! null) {out.flush();out.close();out null;}} catch (IOException e) {e.printStackTrace();}} // end finally}
}
包含 main 方法的 Test 类测试具体效果 import java.io.File;
import java.util.List;
import java.util.ArrayList;public class Test {public static void main(String[] args) {ListEmployeeDTO employeeDTOList new ArrayList();EmployeeDTO emp_1 new EmployeeDTO();emp_1.setNo(1);emp_1.setName(张三);emp_1.setGender(男);emp_1.setPortrait(D:/1715284526222417922.jpg);EmployeeDTO emp_2 new EmployeeDTO();emp_2.setNo(2);emp_2.setName(李四);emp_2.setGender(男);emp_2.setPortrait(D:\\bmptest.bmp);EmployeeDTO emp_3 new EmployeeDTO();emp_3.setNo(3);emp_3.setName(王二);emp_3.setGender(女);emp_3.setPortrait(D:\\113.jpg);EmployeeDTO emp_4 new EmployeeDTO();emp_4.setNo(4);emp_4.setName(涂军);emp_4.setGender(男);emp_4.setPortrait(D:\\309446533.gif);employeeDTOList.add(emp_1);employeeDTOList.add(emp_2);employeeDTOList.add(emp_3);employeeDTOList.add(emp_4);File file new File(D:\\ws\\tmpdir\\out.xlsx);String tempFilePath D:\\ws\\tmpdir\\temp.png;ImageExcelUtils.createExcelFile(employeeDTOList, file, tempFilePath);}
}