首页 > 编程语言 >【工具】Java Excel转图片

【工具】Java Excel转图片

时间:2024-09-24 13:57:18浏览次数:10  
标签:Java java int graphics Excel 边框 new import 图片


【工具】Java Excel转图片

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);
        }
    }
}

设置指定字体

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);
        }
    }
}

支持公式 固定了一个字体

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);
        }
    }
}

标签:Java,java,int,graphics,Excel,边框,new,import,图片
From: https://blog.51cto.com/u_14976802/12098750

相关文章

  • DsExcel,GcExcel .NET 7.2.2 Crack
    DsExcel,GcExcel.NET 高速C#.NETExcel电子表格API库Excel文档解决方案(DsExcel,以前称为GcExcel).NET版本允许您使用此快速电子表格API在C#.NET6+、.NETCore、.NETFramework和Xamarin跨平台应用程序中以编程方式创建、编辑、导入和导出Excel电子表格。......
  • Java 音视频处理详解
    Java作为一种通用的编程语言,具备强大的跨平台能力和丰富的第三方库支持,使其在音视频处理领域也能大展拳脚。本文将详细介绍Java在音视频处理中的常用技术和方法,包括音视频捕获、处理、存储和播放。通过对实际代码示例的讲解,帮助读者深入理解并掌握Java音视频处理的核心内容。......
  • Java 数据库存储数组的方法
    在现代软件开发中,数组是常用的数据结构之一。然而,在关系数据库中直接存储数组并不是一个简单的任务。关系数据库通常擅长存储简单的数据类型如整数、字符串和日期等,但对于复杂的数据类型如数组、列表或对象,通常需要采用特殊的方法进行处理。本文将详细介绍几种在Java中将数组存储到......
  • java 实现AES的CBC、CFB、OFB加解密
    1.CBC(CipherBlockChaining,密码分组链接模式)概述CBC模式是一种常见的块密码工作模式,通过将每个明文块与前一个密文块进行异或操作,再进行加密,从而增强数据的安全性。工作原理初始向量(IV,InitializationVector):CBC模式需要一个随机生成的IV来确保相同明文在不同加密过......
  • 【Java】JVM基本组成
    一、JDK、JRE、JVM        JDK:全称“JavaDevelopmentKit”Java开发工具包,提供javac编译器、jheap、jconsole等监控工具;        JRE:全称“JavaRuntimeEnvironment” Java运行环境,提供classLibrary核心类库+JVM;             ......
  • 【Java】并发编程的艺术:悲观锁、乐观锁与死锁管理
    目录一、乐观锁和悲观锁二、ReadWriteLock三、StampedLock四、Semaphore五、死锁的条件六、如何发现死锁七、如何避免死锁一、乐观锁和悲观锁        悲观锁(PessimisticLocking)具有强烈的独占和排他特性。它指的是对数据被外界修改持保守态度。因此,在整......
  • java中的静态方法
    /*1.被static修饰的成员,称之为类成员,在对象创建之前就存在于方法区中静态区2.被static修饰的成员,可以通过类名直接访问使用,非静态的成员必须要通过对象去调用3.static可以修饰成员变量和成员方法4.非静态的成员方法既可以访问静态的成员[变量或方法],也......
  • EXCEL进行数据分析
    一、周报业务逻辑讲解1.成果可根据平台和日期变动所有数据 转化率和变化趋势      进店转化率=进店人数/曝光人数      下单转化率=下单人数/进店人数      数据趋势:流量变大,承接能力跟不上,转化率会下降结果指标和过程指标......
  • JavaScript 对象的基本操作及相关知识点详解
    在JavaScript中,对象是一种基本的数据结构,以键值对形式保存数据且数据没有顺序,它可以包含多种数据类型的属性和方法。1.创建对象的方法字面量写法: let自定义对象名={}构造函数写法:let自定义对象名=newObject();//字面量写法letperson={};//构造函数......
  • 勤哲Excel服务器自动生成网络工程管理信息化系统
    在当今信息化技术高速发展的时代,有线网络工程作为信息交流和数据传输的重要基础设施,已经渗透到各个领域。有线网络工程的规模和复杂性日益增长,对其全面管理的需求也与日俱增。传统的人工管理已经无法满足大规模网络环境下的管理需求,因此,信息化管理成为必然的趋势。据悉,有线网络......