【工具】Java Excel转图片
java
package com.yj.luban.modules.office.excel;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Font;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class ExcelToImg {
public static void main(String[] args) throws IOException {
// Excel 文件路径
String excelFilePath = "D:\\WORK\\workspace_tools\\Office\\excelToImg\\工时.xlsx";
FileInputStream excelFile = new FileInputStream(new File(excelFilePath));
// 创建 Workbook 对象
Workbook workbook = new XSSFWorkbook(excelFile);
Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
// 创建一个临时的 BufferedImage 用于测量文本宽度
BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D tempGraphics = tempImage.createGraphics();
Font font = new Font("Arial", Font.PLAIN, 12);
tempGraphics.setFont(font);
FontMetrics fontMetrics = tempGraphics.getFontMetrics();
// 动态计算每列的宽度
int totalColumns = getMaxColumns(sheet);
int[] columnWidths = new int[totalColumns];
int rowHeight = fontMetrics.getHeight() + 10; // 行高根据字体高度动态调整
// 遍历所有单元格内容,计算最大列宽
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row == null) continue;
for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
Cell cell = row.getCell(colIndex);
if (cell != null) {
String cellValue = cell.toString();
int textWidth = fontMetrics.stringWidth(cellValue) + 10; // 加 10 像素边距
columnWidths[colIndex] = Math.max(columnWidths[colIndex], textWidth);
} else {
columnWidths[colIndex] = Math.max(columnWidths[colIndex], 100); // 设置默认最小宽度
}
}
}
// 计算图像总宽度和总高度
int imageWidth = 50; // 初始边距
for (int colWidth : columnWidths) {
imageWidth += colWidth;
}
int imageHeight = (sheet.getLastRowNum() + 1) * rowHeight + 100; // 加上顶部和底部边距
// 创建最终的 BufferedImage
BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
// 设置白色背景
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, imageWidth, imageHeight);
// 设置字体
graphics.setColor(Color.BLACK);
graphics.setFont(font);
// 起始坐标
int startX = 50;
int startY = 50;
// 绘制每个单元格的内容和样式
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row == null) continue;
int x = startX;
for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
Cell cell = row.getCell(colIndex);
String cellValue = (cell != null) ? cell.toString() : "";
// 绘制单元格内容
graphics.drawString(cellValue, x + 5, startY + rowIndex * rowHeight + rowHeight / 2);
// 绘制单元格边框
if (cell != null) {
CellStyle cellStyle = cell.getCellStyle();
drawCellBorders(graphics, x, startY + rowIndex * rowHeight, columnWidths[colIndex], rowHeight, cellStyle);
}
// 移动到下一个单元格的位置
x += columnWidths[colIndex];
}
}
// 释放资源
graphics.dispose();
workbook.close();
tempGraphics.dispose();
// 保存图片
ImageIO.write(image, "png", new File("D:\\WORK\\workspace_tools\\Office\\excelToImg\\a.png"));
System.out.println("Excel 样式和边框转换为图片成功!");
}
// 获取最大列数
private static int getMaxColumns(Sheet sheet) {
int maxColumns = 0;
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row != null && row.getLastCellNum() > maxColumns) {
maxColumns = row.getLastCellNum();
}
}
return maxColumns;
}
// 绘制单元格边框
private static void drawCellBorders(Graphics2D graphics, int x, int y, int width, int height, CellStyle style) {
// 设置边框颜色为黑色
graphics.setColor(Color.BLACK);
// 绘制顶部边框
if (style.getBorderTop() != BorderStyle.NONE) {
graphics.drawLine(x, y, x + width, y);
}
// 绘制底部边框
if (style.getBorderBottom() != BorderStyle.NONE) {
graphics.drawLine(x, y + height, x + width, y + height);
}
// 绘制左侧边框
if (style.getBorderLeft() != BorderStyle.NONE) {
graphics.drawLine(x, y, x, y + height);
}
// 绘制右侧边框
if (style.getBorderRight() != BorderStyle.NONE) {
graphics.drawLine(x + width, y, x + width, y + height);
}
}
}
设置指定字体
java
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class ExcelToStyledImageWithBorders {
public static void main(String[] args) throws IOException {
// Excel 文件路径
String excelFilePath = "example.xlsx";
FileInputStream excelFile = new FileInputStream(new File(excelFilePath));
// 创建 Workbook 对象
Workbook workbook = new XSSFWorkbook(excelFile);
Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
// 创建一个临时的 BufferedImage 用于测量文本宽度
BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D tempGraphics = tempImage.createGraphics();
// 使用 SimSun 字体,支持中文字符
Font font = new Font("SimSun", Font.PLAIN, 12);
tempGraphics.setFont(font);
FontMetrics fontMetrics = tempGraphics.getFontMetrics();
// 动态计算每列的宽度
int totalColumns = getMaxColumns(sheet);
int[] columnWidths = new int[totalColumns];
int rowHeight = fontMetrics.getHeight() + 10; // 行高根据字体高度动态调整
// 遍历所有单元格内容,计算最大列宽
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row == null) continue;
for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
Cell cell = row.getCell(colIndex);
if (cell != null) {
String cellValue = cell.toString();
int textWidth = fontMetrics.stringWidth(cellValue) + 10; // 加 10 像素边距
columnWidths[colIndex] = Math.max(columnWidths[colIndex], textWidth);
} else {
columnWidths[colIndex] = Math.max(columnWidths[colIndex], 100); // 设置默认最小宽度
}
}
}
// 计算图像总宽度和总高度
int imageWidth = 50; // 初始边距
for (int colWidth : columnWidths) {
imageWidth += colWidth;
}
int imageHeight = (sheet.getLastRowNum() + 1) * rowHeight + 100; // 加上顶部和底部边距
// 创建最终的 BufferedImage
BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
// 设置白色背景
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, imageWidth, imageHeight);
// 设置字体,确保支持中文
graphics.setFont(font);
graphics.setColor(Color.BLACK);
// 起始坐标
int startX = 50;
int startY = 50;
// 绘制每个单元格的内容和样式
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row == null) continue;
int x = startX;
for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
Cell cell = row.getCell(colIndex);
String cellValue = (cell != null) ? cell.toString() : "";
// 绘制单元格内容
graphics.drawString(cellValue, x + 5, startY + rowIndex * rowHeight + rowHeight / 2);
// 绘制单元格边框
if (cell != null) {
CellStyle cellStyle = cell.getCellStyle();
drawCellBorders(graphics, x, startY + rowIndex * rowHeight, columnWidths[colIndex], rowHeight, cellStyle);
}
// 移动到下一个单元格的位置
x += columnWidths[colIndex];
}
}
// 释放资源
graphics.dispose();
workbook.close();
tempGraphics.dispose();
// 保存图片
ImageIO.write(image, "png", new File("excel_styled_with_borders_image.png"));
System.out.println("Excel 样式和边框转换为图片成功!");
}
// 获取最大列数
private static int getMaxColumns(Sheet sheet) {
int maxColumns = 0;
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row != null && row.getLastCellNum() > maxColumns) {
maxColumns = row.getLastCellNum();
}
}
return maxColumns;
}
// 绘制单元格边框
private static void drawCellBorders(Graphics2D graphics, int x, int y, int width, int height, CellStyle style) {
// 设置边框颜色为黑色
graphics.setColor(Color.BLACK);
// 绘制顶部边框
if (style.getBorderTop() != BorderStyle.NONE) {
graphics.drawLine(x, y, x + width, y);
}
// 绘制底部边框
if (style.getBorderBottom() != BorderStyle.NONE) {
graphics.drawLine(x, y + height, x + width, y + height);
}
// 绘制左侧边框
if (style.getBorderLeft() != BorderStyle.NONE) {
graphics.drawLine(x, y, x, y + height);
}
// 绘制右侧边框
if (style.getBorderRight() != BorderStyle.NONE) {
graphics.drawLine(x + width, y, x + width, y + height);
}
}
}
支持公式 固定了一个字体
java
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class ExcelToStyledImageWithBordersAndFormula {
public static void main(String[] args) throws IOException {
// Excel 文件路径
String excelFilePath = "example.xlsx";
FileInputStream excelFile = new FileInputStream(new File(excelFilePath));
// 创建 Workbook 对象
Workbook workbook = new XSSFWorkbook(excelFile);
Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
// 创建 FormulaEvaluator 对象来解析公式
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
// 创建一个临时的 BufferedImage 用于测量文本宽度
BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D tempGraphics = tempImage.createGraphics();
// 使用 SimSun 字体,支持中文字符
Font font = new Font("SimSun", Font.PLAIN, 12);
tempGraphics.setFont(font);
FontMetrics fontMetrics = tempGraphics.getFontMetrics();
// 动态计算每列的宽度
int totalColumns = getMaxColumns(sheet);
int[] columnWidths = new int[totalColumns];
int rowHeight = fontMetrics.getHeight() + 10; // 行高根据字体高度动态调整
// 遍历所有单元格内容,计算最大列宽
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row == null) continue;
for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
Cell cell = row.getCell(colIndex);
if (cell != null) {
String cellValue = getCellValue(cell, formulaEvaluator); // 获取单元格值,包含公式解析
int textWidth = fontMetrics.stringWidth(cellValue) + 20; // 加 20 像素边距
columnWidths[colIndex] = Math.max(columnWidths[colIndex], textWidth);
} else {
columnWidths[colIndex] = Math.max(columnWidths[colIndex], 100); // 设置默认最小宽度
}
}
}
// 计算图像总宽度和总高度
int imageWidth = 100; // 初始边距,增加更多的边距以防止截断
for (int colWidth : columnWidths) {
imageWidth += colWidth;
}
int imageHeight = (sheet.getLastRowNum() + 1) * rowHeight + 100; // 加上顶部和底部边距
// 创建最终的 BufferedImage
BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
// 设置白色背景
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, imageWidth, imageHeight);
// 设置字体,确保支持中文
graphics.setFont(font);
graphics.setColor(Color.BLACK);
// 起始坐标
int startX = 50;
int startY = 50;
// 绘制每个单元格的内容和样式
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row == null) continue;
int x = startX;
for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
Cell cell = row.getCell(colIndex);
String cellValue = (cell != null) ? getCellValue(cell, formulaEvaluator) : "";
// 绘制单元格内容
graphics.drawString(cellValue, x + 5, startY + rowIndex * rowHeight + rowHeight / 2);
// 绘制单元格边框
if (cell != null) {
CellStyle cellStyle = cell.getCellStyle();
drawCellBorders(graphics, x, startY + rowIndex * rowHeight, columnWidths[colIndex], rowHeight, cellStyle);
}
// 移动到下一个单元格的位置
x += columnWidths[colIndex];
}
}
// 释放资源
graphics.dispose();
workbook.close();
tempGraphics.dispose();
// 保存图片
ImageIO.write(image, "png", new File("excel_styled_with_borders_and_formula_image.png"));
System.out.println("Excel 样式和边框、公式转换为图片成功!");
}
// 获取单元格值,并解析公式
private static String getCellValue(Cell cell, FormulaEvaluator formulaEvaluator) {
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
return String.valueOf(cell.getNumericCellValue());
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case FORMULA:
// 使用 FormulaEvaluator 解析公式
CellValue evaluatedValue = formulaEvaluator.evaluate(cell);
switch (evaluatedValue.getCellType()) {
case STRING:
return evaluatedValue.getStringValue();
case NUMERIC:
return String.valueOf(evaluatedValue.getNumberValue());
case BOOLEAN:
return String.valueOf(evaluatedValue.getBooleanValue());
default:
return " ";
}
default:
return " ";
}
}
// 获取最大列数
private static int getMaxColumns(Sheet sheet) {
int maxColumns = 0;
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
Row row = sheet.getRow(rowIndex);
if (row != null && row.getLastCellNum() > maxColumns) {
maxColumns = row.getLastCellNum();
}
}
return maxColumns;
}
// 绘制单元格边框
private static void drawCellBorders(Graphics2D graphics, int x, int y, int width, int height, CellStyle style) {
// 设置边框颜色为黑色
graphics.setColor(Color.BLACK);
// 绘制顶部边框
if (style.getBorderTop() != BorderStyle.NONE) {
graphics.drawLine(x, y, x + width, y);
}
// 绘制底部边框
if (style.getBorderBottom() != BorderStyle.NONE) {
graphics.drawLine(x, y + height, x + width, y + height);
}
// 绘制左侧边框
if (style.getBorderLeft() != BorderStyle.NONE) {
graphics.drawLine(x, y, x, y + height);
}
// 绘制右侧边框
if (style.getBorderRight() != BorderStyle.NONE) {
graphics.drawLine(x + width, y, x + width, y + height);
}
}
}