看到一篇好用的excel转图片的代码,封装和改动了一部分
原文https://www.cnblogs.com/newflydd/p/4912662.html#top

调整可以导出带图片的excel,支持表达式

用到jar包

<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version>
</dependency>
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version>
</dependency>

不多说了,直接上代码

package com.example.excel;import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFShape;
import org.apache.poi.hssf.usermodel.HSSFSheet;
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.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Font;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** width:pix=getColumnWidthInPixels*1.15* height:pix=getHeightInPoints*96/72* <p>* 本示例用来读取Excel报表文件,并力图将报表无差别转化成PNG图片* 使用POI读取Excel各项数据* 使用JAVA 2D绘制PNG* 本示例基本实现了常见Excel的所有样式输出,但Office2007以后的版本添加了条件样式功能,,所以无法实现* 今后可以通过关键字标注等方法,在Excel中需要加入条件样式的单元格用注解标明,使用JAVA计算得出样因为POI的API无法读取条件样式式再绘制出来* 中文乱码问题请查看excel中字体 在本地是否安装* 可以导出图片* <p>*/
public class DrawFromExcel {/*** excel转图片** @param excelUrl excel路径* @param path     图片存储路径* @throws IOException,InvalidFormatException 异常*/public static void excelToImage(String excelUrl, String path) throws IOException, InvalidFormatException {Workbook wb = WorkbookFactory.create(new File(excelUrl));wb.close();// 获取每个Sheet表for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) {// 图片宽度int imageWidth;// 图片高度int imageHeight;//第一个工作表Sheet sheet = wb.getSheetAt(sheetIndex);// 获取工作表是否存在图片Map<String, PictureData> maplist = null;if (excelUrl.endsWith(".xls")) {maplist = getPictures1((HSSFSheet) sheet);} else if (excelUrl.endsWith(".xlsx")) {maplist = getPictures2((XSSFSheet) sheet);}// 获取整个sheet中合并单元格组合的集合List<CellRangeAddress> rangeAddress = sheet.getMergedRegions();//检查区域内是否存在数据int rowSize = sheet.getPhysicalNumberOfRows();int colSize = sheet.getRow(0).getPhysicalNumberOfCells();if (rowSize == 0 || colSize == 0) {continue;}// 遍历需要扫描的区域UserCell[][] cells = new UserCell[rowSize][colSize];int[] rowPixPos = new int[rowSize + 1];rowPixPos[0] = 0;int[] colPixPos = new int[colSize + 1];colPixPos[0] = 0;float height = 0f;float width = 0f;for (int i = 0; i < rowSize; i++) {for (int j = 0; j < colSize; j++) {cells[i][j] = new UserCell();cells[i][j].setCell(sheet.getRow(i).getCell(j));cells[i][j].setRow(i);cells[i][j].setCol(j);//行列不可以隐藏boolean ifShow = !(sheet.isColumnHidden(j) || sheet.getRow(i).getZeroHeight());cells[i][j].setShow(ifShow);// 计算所求区域宽度 如果该单元格是隐藏的,则置宽度为0float widthPix = !ifShow ? 0 : sheet.getColumnWidthInPixels(j);if (i == 0) {width += widthPix;}colPixPos[j + 1] = (int) (widthPix * 1.15 + colPixPos[j]);}// 计算所求区域高度 行序列不能隐藏boolean ifShow = !sheet.getRow(i).getZeroHeight();// 如果该单元格是隐藏的,则置高度为0float heightPoint = !ifShow ? 0 : sheet.getRow(i).getHeightInPoints();height += heightPoint;rowPixPos[i + 1] = (int) (heightPoint * 96 / 72) + rowPixPos[i];}imageHeight = (int) (height * 96 / 72);imageWidth = (int) (width * 115 / 100);List<Grid> grids = getGrids(wb, rangeAddress, rowSize, colSize, cells, rowPixPos, colPixPos, maplist);// 绘图draw(imageWidth, imageHeight, grids, path);}}/*** 根据表格制作网格** @param wb           excel* @param rangeAddress 合并单元格组合* @param rowSize      行大小* @param colSize      列大小* @param cells        单元格* @param rowPixPos    需要扫描的行大小* @param colPixPos    需要扫描的列大小* @return 网格数据*/private static List<Grid> getGrids(Workbook wb, List<CellRangeAddress> rangeAddress, int rowSize, int colSize, UserCell[][] cells, int[] rowPixPos, int[] colPixPos, Map<String, PictureData> dataMap) {List<Grid> grids = new ArrayList<>();for (int i = 0; i < rowSize; i++) {for (int j = 0; j < colSize; j++) {//当前表格Cell cell = cells[i][j].getCell();Grid grid = new Grid();// 设置坐标和宽高grid.setX(colPixPos[j]);grid.setY(rowPixPos[i]);grid.setWidth(colPixPos[j + 1] - colPixPos[j]);grid.setHeight(rowPixPos[i + 1] - rowPixPos[i]);grid.setRow(cells[i][j].getRow());grid.setCol(cells[i][j].getCol());grid.setShow(cells[i][j].isShow());// 判断是否为合并单元格int[] isInMergedStatus = isInMerged(grid.getRow(), grid.getCol(), rangeAddress);if (cell == null || (isInMergedStatus[0] == 0 && isInMergedStatus[1] == 0)) {continue;} else if (isInMergedStatus[0] != -1 && isInMergedStatus[1] != -1) {// 此单元格是合并单元格,并且属于第一个单元格,则需要调整网格大小int lastRowPos = Math.min(isInMergedStatus[0], rowSize - 1);int lastColPos = Math.min(isInMergedStatus[1], colSize - 1);grid.setWidth(colPixPos[lastColPos + 1] - colPixPos[j]);grid.setHeight(rowPixPos[lastRowPos + 1] - rowPixPos[i]);}// 单元格背景颜色CellStyle cs = cell.getCellStyle();if (cs.getFillPatternEnum() == FillPatternType.SOLID_FOREGROUND) {grid.setBgColor(cell.getCellStyle().getFillForegroundColorColor());}// 设置字体org.apache.poi.ss.usermodel.Font font = wb.getFontAt(cs.getFontIndex());grid.setFont(font);// 设置字体前景色if (font instanceof XSSFFont) {XSSFFont xf = (XSSFFont) font;grid.setFtColor(xf.getXSSFColor());}// 设置文本String strCell;if (cell.getCellTypeEnum() == CellType.NUMERIC) {if (DateUtil.isCellDateFormatted(cell)) {strCell = DateFormatUtils.format(cell.getDateCellValue(), "yyyy-MM-dd");} else {NumberFormat nf = NumberFormat.getInstance();strCell = String.valueOf(nf.format(cell.getNumericCellValue())).replace(",", "");}} else if (cell.getCellTypeEnum() == CellType.STRING) {strCell = String.valueOf(cell.getStringCellValue());} else if (cell.getCellTypeEnum() == CellType.BOOLEAN) {strCell = String.valueOf(cell.getBooleanCellValue());} else if (cell.getCellTypeEnum() == CellType.ERROR) {strCell = "错误类型";} else {strCell = "";}// 如果为空可能单元格是图片if ("".equals(strCell)) {PictureData pictureData = dataMap.get(i + "-" + j);if (pictureData != null) {grid.setData(pictureData.getData());}}if (cell.getCellStyle().getDataFormatString().contains("0.00%")) {try {double dbCell = Double.parseDouble(strCell);strCell = new DecimalFormat("#.00").format(dbCell * 100) + "%";} catch (NumberFormatException ignored) {}}grid.setText(strCell.matches("\\w*\\.0") ? strCell.substring(0, strCell.length() - 2) : strCell);grids.add(grid);}}return grids;}/*** 绘图** @param imageWidth  图片宽度* @param imageHeight 图片高度* @param grids       绘制图片的内容*/public static void draw(int imageWidth, int imageHeight, List<Grid> grids, String path) throws IOException {BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);Graphics2D g2d = image.createGraphics();// 平滑字体g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);g2d.setRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST, 140);g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT);g2d.setColor(Color.white);g2d.fillRect(0, 0, imageWidth, imageHeight);// 绘制表格for (Grid g : grids) {if (!g.isShow()) {continue;}// 绘制背景色g2d.setColor(g.getBgColor() == null ? Color.white : g.getBgColor());g2d.fillRect(g.getX(), g.getY(), g.getWidth(), g.getHeight());// 绘制边框g2d.setColor(Color.black);g2d.setStroke(new BasicStroke(1));g2d.drawRect(g.getX(), g.getY(), g.getWidth(), g.getHeight());// 绘制文字,居中显示g2d.setColor(g.getFtColor());Font font = g.getFont();FontMetrics fm = g2d.getFontMetrics(font);// 获取将要绘制的文字宽度int strWidth = fm.stringWidth(g.getText());g2d.setFont(font);// 图片if (g.getData() != null && g.getData().length > 0) {InputStream inputStream = new ByteArrayInputStream(g.getData());BufferedImage bg = ImageIO.read(inputStream);g2d.drawImage(bg.getScaledInstance(g.getWidth(), g.getHeight(), Image.SCALE_DEFAULT),g.getX(),g.getY(), null);}// 文字else {g2d.drawString(g.getText(),g.getX() + (g.getWidth() - strWidth) / 2,g.getY() + (g.getHeight() - font.getSize()) / 2 + font.getSize());}}g2d.dispose();//生成图片String imgUrl = path + File.separator + System.currentTimeMillis() + ".png";ImageIO.write(image, "png", new File(imgUrl));}/*** 判断Excel中的单元格是否为合并单元格** @param row          当前行号* @param col          当前列号* @param rangeAddress 整个sheet中合并单元格组合的集合* @return 如果不是合并单元格返回{-1,-1},如果是合并单元格并且是一个单元格返回{lastRow,lastCol},* 如果是合并单元格并且不是第一个格子返回{0,0}*/private static int[] isInMerged(int row, int col, List<CellRangeAddress> rangeAddress) {int[] isInMergedStatus = {-1, -1};for (CellRangeAddress cra : rangeAddress) {if (row == cra.getFirstRow() && col == cra.getFirstColumn()) {isInMergedStatus[0] = cra.getLastRow();isInMergedStatus[1] = cra.getLastColumn();return isInMergedStatus;}if (row >= cra.getFirstRow() && row <= cra.getLastRow() && col >= cra.getFirstColumn() && col <= cra.getLastColumn()) {isInMergedStatus[0] = 0;isInMergedStatus[1] = 0;return isInMergedStatus;}}return isInMergedStatus;}/*** 获取图片和位置 (xls)** @param sheet -* @return -* Z*/public static Map<String, PictureData> getPictures1(HSSFSheet sheet) {Map<String, PictureData> map = new HashMap<>();List<HSSFShape> list = sheet.getDrawingPatriarch().getChildren();for (HSSFShape shape : list) {if (shape instanceof HSSFPicture) {HSSFPicture picture = (HSSFPicture) shape;HSSFClientAnchor cAnchor = (HSSFClientAnchor) picture.getAnchor();PictureData pdata = picture.getPictureData();// 行号-列号String key = cAnchor.getRow1() + "-" + cAnchor.getCol1();map.put(key, pdata);}}return map;}/*** 获取图片和位置 (xlsx)** @param sheet -* @return -*/public static Map<String, PictureData> getPictures2(XSSFSheet sheet) {Map<String, PictureData> map = new HashMap<>();List<POIXMLDocumentPart> list = sheet.getRelations();for (POIXMLDocumentPart part : list) {if (part instanceof XSSFDrawing) {XSSFDrawing drawing = (XSSFDrawing) part;List<XSSFShape> shapes = drawing.getShapes();for (XSSFShape shape : shapes) {XSSFPicture picture = (XSSFPicture) shape;XSSFClientAnchor anchor = picture.getPreferredSize();CTMarker marker = anchor.getFrom();// 行号-列号String key = marker.getRow() + "-" + marker.getCol();map.put(key, picture.getPictureData());}}}return map;}}
package com.example.excel;import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.xssf.usermodel.XSSFColor;import java.awt.*;public class Grid {/*** 是否显示*/private boolean show;/*** 对应Excel中的row,也可以理解为cells[i][j]的i*/private int row;/*** 对应Excel中的col,也可以理解为cells[i][j]的j*/private int col;/*** x坐标*/private int x;/*** y坐标*/private int y;private int width;private int height;private String text;private byte[] data;/*** 字体 new Font("微软雅黑", Font.PLAIN, 12);*/private Font font;private Color bgColor = null;private Color ftColor = null;public int getRow() {return row;}public void setRow(int row) {this.row = row;}public int getCol() {return col;}public void setCol(int col) {this.col = col;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public boolean isShow() {return show;}public void setShow(boolean show) {this.show = show;}public int getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public String getText() {return text;}public void setText(String text) {this.text = text;}public byte[] getData() {return data;}public void setData(byte[] data) {this.data = data;}public Color getBgColor() {return bgColor;}/*** 将poi.ss.usermodel.Color 转换成  java.awt.Color* <a href="http://home.cnblogs.com/u/309701/" target="_blank">@param</a> color*/public void setBgColor(org.apache.poi.ss.usermodel.Color color) {this.bgColor = poiColor2awtColor(color);}public void setBgColor(java.awt.Color color) {this.bgColor = color;}public Color getFtColor() {return ftColor;}public void setFtColor(org.apache.poi.ss.usermodel.Color color) {this.ftColor = poiColor2awtColor(color);}public Font getFont() {return font;}public void setFont(org.apache.poi.ss.usermodel.Font font) {if (font != null) {this.font = new java.awt.Font(font.getFontName(), Font.BOLD, font.getFontHeight() / 20 + 2);}}private java.awt.Color poiColor2awtColor(org.apache.poi.ss.usermodel.Color color) {java.awt.Color awtColor = null;//.xlsxif (color instanceof XSSFColor) {XSSFColor xc = (XSSFColor) color;String rgbHex = xc.getARGBHex();if (rgbHex != null) {awtColor = new Color(Integer.parseInt(rgbHex.substring(2), 16));}}//.xlselse if (color instanceof HSSFColor) {HSSFColor hc = (HSSFColor) color;short[] s = hc.getTriplet();if (s != null) {awtColor = new Color(s[0], s[1], s[2]);}}return awtColor;}
}
package com.example.excel;import org.apache.poi.ss.usermodel.Cell;import java.awt.*;public class UserCell implements Comparable<UserCell> {private Cell cell;private int row;private int col;private boolean show;private String text = "";private Color color = null;public Cell getCell() {return cell;}public void setCell(Cell cell) {this.cell = cell;}public int getRow() {return row;}public void setRow(int row) {this.row = row;}public int getCol() {return col;}public void setCol(int col) {this.col = col;}public boolean isShow() {return show;}public void setShow(boolean show) {this.show = show;}public String getText() {return text;}public void setText(String text) {this.text = text;}public Color getColor() {return color;}public void setColor(Color color) {this.color = color;}@Overridepublic int compareTo(UserCell uc) {try {double meDouble = Double.parseDouble(this.getText().replace("%", ""));double heDouble = Double.parseDouble(uc.getText().replace("%", ""));if (meDouble < heDouble) {return -1;} else if (meDouble > heDouble) {return 1;}} catch (Exception ignored) {}return 0;}
}

Java Excel转图片相关推荐

  1. java excel复制图片_java实现图片用Excel画出来

    本文实例为大家分享了java用Excel将图片画出来的具体代码,供大家参考,具体内容如下 能够将任何图片在excel上利用单元格背景完整的描绘出来. 像网络上出现的用excel画出超级玛丽等等,各种图 ...

  2. Java excel大批量图片数据导出解决内存溢出问题

    如果使用poi直接将所有图片一张张写到excel里,最后excel里图片达到10000张之后,内存就快爆掉了,所以,使用该方法将图片写到磁盘里,最后一次性替换掉,目前没有找到更好的方法,暂时使用该方法 ...

  3. Java Excel 插入图片

    在POI中有HSSFPatriarch对象,该对象为画图的顶级管理器,它的createPicture(anchor, pictureIndex)方法就能够在Excel插入一张图片.所以要在Excel中 ...

  4. java excel poi 图片大小_Apache POI Excel工作表:在保持比例的同时调整图片大小

    // Excel width, not character width width = Truncate([{Number of Visible Characters} * {Maximum Digi ...

  5. java excel 导出图片_JAVA 使用 POI 导出 EXCEL 自定义背景颜色

    开发中常用表格导入和导出 Excel 是常见的功能. 在这里分享下使用 POI 导出表格的简单实现,也是为大家提供个思路吧,抛砖引玉,话不多说直接上代码. 1.项目引入 maven 依赖 <!- ...

  6. java 导出excel 附带图片

    java 导出excel 附带图片,思路将后台数据里保存的图片url转为file ,添加到excel里导出 代码示例 String imgPath = filePath +item.getFilePa ...

  7. Java中world、PDF、Excel转图片

    相对来说world.pdf转图片还是比较简单的,world.pdf转html坑是最多的.不过我们这篇文章只写world.pdf转图片,后者我将会用另一篇文章就行讲述. 原理: world.Excel转 ...

  8. java导出excel插入图片

    首项需要的jar包有: 1.poi-3.8-20120326.jar 2.commons-codec-1.10.jar 代码:package com.demo; import java.awt.ima ...

  9. java导出excel带图片_JAVA的poi实现模版导出excel(带图片).doc

    JAVA的poi实现模版导出excel(带图片) 下面是本人使用java的poi实现使用模板到处excel,内容包含图片,使用两种不同的方式实现其到处excel.但是使用jxl实现到处excel只能到 ...

  10. java下载附件给(pdf、pptx、word、excel、图片)添加水印

    java下载附件给(pdf.pptx.word.excel.图片)添加水印 使用组件 poi itext spire.xls ooxml-schemas twelvemonkeys.imageio 等 ...

最新文章

  1. java使用ireport生成报表_JasperReport(3)——Java简单使用IReport生成的文件建立报表...
  2. [转]pthread用于进程间通信
  3. 推荐几本对创业者很有用的书籍
  4. php curl和file get,PHP cURL与file_get_contents
  5. 【Java】我的第一个 JAVA 程序:Hello,world!
  6. Spark Structured SQL报错:Stream stream joins without equality predicate is not supported
  7. Python计算从n个元素中任选i个的组合数C(n,i)
  8. 关于域名系统DNS解析IP地址的一些总结
  9. CNN 卷积神经网络 池化层Pooling 动手学深度学习v2 pytorch
  10. 机器学习十大算法简介
  11. Ant Design 遭删库!
  12. “你还有什么事想问”——作为程序员如何回答面试官的问题
  13. 雷军,扎克伯格,乔布斯等巨佬的办公桌
  14. Termux解析公网ipv6——从全世界各地连接你的Termux
  15. 花旗软件DWH实习回顾
  16. java基础面试题-
  17. css调颜色,CSS3 简单的调色板
  18. python代码中的中文语法错误:SyntaxError: Non-ASCII character ‘\xe5‘ in file trade.py on line 7
  19. SM8S36CA-汽车TVS瞬态抑制二极管
  20. canvas插件 fabric.js 使用

热门文章

  1. 夏书祥-淘宝考试最新答案
  2. uni-app 生成安卓证书
  3. 西门子S7-200SMART四种密码解密软件
  4. BeyondCompare3提示许可密钥过期完美解决方法
  5. MOSFET知识小结
  6. 易用宝项目记录day1-springdatajpa
  7. 矿井下无线基站和地面服务器,煤矿井下无线通信系统_矿井通信
  8. loadrunner压力测试一般使用流程
  9. 计算机数据库技术的应用现状,计算机数据库技术的发展及应用
  10. 自然语言处理NLP技术里程碑、知识结构、研究方向和机构导师(公号回复“NLP总结”下载彩标PDF典藏版资料)