基于pio实现的java excel导出、合并单元格导出

再复杂的excel导出也是基于最朴实的,设置单元格样式,填充数据,设置表头,单元格合并几个语法,然后我再说点要注意的,单元格是用坐标轴表示位置的,是从(0,0)开始的。还有个要注意的就是设置样式,合并指定单元格,设置行宽行高这些语法,都是要指定某一格单元格,在使用这些语法的时候首先要创建单元格,这个单元格单元格要是不存在 你给这个单元格创建样式和合并或者设置行宽行高 就会报空指针

完整代码我放文章末尾 我先描述一下语法

// 创建新的Excel工作簿
XSSFWorkbook workbook = new XSSFWorkbook();

// 在工作簿中创建新的工作表
XSSFSheet sheet = workbook.createSheet(sheetName);

// 创建表头行
XSSFRow headerRow = sheet.createRow(0);

// 设置第一大行标题
XSSFCell cell0 = headerRow.createCell(0);
cell0.setCellValue(title);

// 合并第一行的单元格,使标题占满整行
//参数说明:1:开始行 2:结束行 3:开始列 4:结束列
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, columnTextArray.length - 1));
//设置样式
cell.setCellStyle(getTitleCellStyle(workbook));
//设置表格样式
private static CellStyle getTitleCellStyle(XSSFWorkbook workbook) {
    XSSFCellStyle cellStyle = workbook.createCellStyle();
    cellStyle.setAlignment(HorizontalAlignment.CENTER);
    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
    cellStyle.setFont(createBoldFont(workbook));
    cellStyle.setBorderTop(BorderStyle.THIN);
    cellStyle.setBorderBottom(BorderStyle.THIN);
    cellStyle.setBorderLeft(BorderStyle.THIN);
    cellStyle.setBorderRight(BorderStyle.THIN);
    cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
    cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
    cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
    cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
    return cellStyle;
}

   //设置指定列宽度

sheet.setColumnWidth(i, maxColumnCount * 256); 

  //可以搭配这个方法

private static void autoAdColumnWidth(XSSFSheet sheet, String[] columnTextArray) {
    int maxColumnCount = 0;
    for (String columnText : columnTextArray) {
        maxColumnCount = Math.max(maxColumnCount, columnText.length());
    }
    maxColumnCount = Math.max(maxColumnCount, 25); // 设置最小宽度为25个字符

    for (int i = 0; i < columnTextArray.length; i++) {
        sheet.setColumnWidth(i, maxColumnCount * 256); // 设置列宽
    }
}

//设置指定行高 数据集有多少行设置比遍历多少行 用fori循环就好

sheet.getRow(i).setHeightInPoints(25);

private static void autoAdjustRowHeight(XSSFSheet sheet, int rowCount) {

    for (int i = 0; i < rowCount; i++) {
        XSSFRow row = sheet.getRow(i);
        if (row == null) {
            row = sheet.createRow(i);
        }
        row.setHeightInPoints(25);
    }
}

  //如果需要小数点位数的话  可以用这个设置

row1.createCell(1).setCellValue(String.valueOf(String.format("%.6f", dto.getNumPrice())));

基本上就是这些语法 然后我再附上工具类 我写的工具类 以及使用方法  有单元格直接导出的, 还有的是按主数据id合并单元格导出的

package com.xtql.SmartProduceManager.utils;

import com.vqor.core.exception.BusinessException;
import com.vqor.core.util.BeanUtil;
import com.vqor.core.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

public class ExcUtil {

   

    public static List<Map<String, Object>> processRowData(List<?> list) {


        List<Map<String, Object>> dataList = new ArrayList<>();

        Map<String, String> rowMap = new LinkedHashMap<>();

        for (Object dto : list) {
            Map<String, Object> map = BeanUtil.getPMap(dto);
            String id = (String) map.get("id");
            if (!rowMap.containsKey(id)) {
                rowMap.put(id, String.valueOf(rowMap.size() + 1));
            }
            map.put("row", rowMap.get(id));
            dataList.add(map);
        }

        return dataList;
    }

    /**
     * //单元格合并 mergeColumn 传入的是一个int数组 传入那一列合并那一列指定合并列
     *  合并规则是  字段名称id相同指定列合并   如果不传数组 就是普通的excel导出
     *   需要序号的话 加入参数实体类加入row字段  数据库返回row字段(只要是数字都行方法内会重新处理row值)  参数数组中 columnTextArray  columnNames   加入 序号 , row  作为第一列就能自动处理
     *
     * @Date:2024-06-22 11:41
     * @Author:yechendong
     */


    public void exportMergeExcel(String sheetName, String title, HttpServletResponse response, List list, String[] columnTextArray, String[] columnNames, int[] mergeColumn) {

        List<Map<String, Object>> dataList = processRowData(list);
        try {

            // 创建新的Excel工作簿
            XSSFWorkbook workbook = new XSSFWorkbook();

            // 在工作簿中创建新的工作表
            XSSFSheet sheet = workbook.createSheet(sheetName);

            // 创建表头行
            XSSFRow headerRow = sheet.createRow(0);

            // 设置第一大行标题
            XSSFCell cell0 = headerRow.createCell(0);
            cell0.setCellValue(title);

            // 合并第一行的单元格,使标题占满整行
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, columnTextArray.length - 1));


            // 设置标题单元格的样式
            CellStyle titleStyle = workbook.createCellStyle();
            titleStyle.setAlignment(HorizontalAlignment.CENTER);
            titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            XSSFFont titleFont = workbook.createFont();
            titleFont.setBold(true);
            titleFont.setFontHeightInPoints((short) 20);
            titleStyle.setFont(titleFont);
            // 设置标题行边框样式

            cell0.setCellStyle(titleStyle);


            // s设置表头
            XSSFRow firstRow = sheet.createRow(1);
            // s设置表头


            for (int i = 0; i < columnTextArray.length; i++) {
                // 创建数据行
                XSSFCell cell = firstRow.createCell(i);
                cell.setCellValue(columnTextArray[i]);
                cell.setCellStyle(getTitleCellStyle(workbook));

            }
            // 遍历数据列表,为每一行填充单元格值
            for (int i = 0; i < dataList.size(); i++) {

                // 获取当前行的 Map 数据
                Map<String, Object> rowData = dataList.get(i);

                // 创建新的数据行
                XSSFRow dataRow = sheet.createRow(i + 2);

                // 遍历属性名称数组,设置单元格值
                for (int j = 0; j < columnNames.length; j++) {
                    // 根据列名从 Map 中获取对应的值
                    Object cellValue = rowData.get(columnNames[j]);

                    // 创建单元格并设置值
                    XSSFCell cell = dataRow.createCell(j);
                    if (cellValue instanceof Date) {
                        cell.setCellValue((Date) cellValue);
                    } else if (cellValue instanceof Number) {
                        cell.setCellValue(((Number) cellValue).doubleValue());
                    } else {
                        cell.setCellValue(cellValue != null ? cellValue.toString() : "");
                    }
                    // 设置单元格样式
                    cell.setCellStyle(getDataCellStyle(workbook));
                }
            }
            //单元格合并
            merge(dataList, mergeColumn, sheet);
            // 自动调整列宽和行高
            // sheet.addMergedRegion(new CellRangeAddress(2, 7, 0, 0));
            autoAdColumnWidth(sheet, columnTextArray);
            autoAdjustRowHeight(sheet, dataList.size() + 2);
            //sheet.getRow(i).setHeightInPoints(25);
            // 设置响应头信息以触发文件下载

            response.setContentType("application/x-msdownload");
            response.setHeader("Content-Disposition", "attachment;Filename=" + "downloadFileName");


            // 将工作簿写入响应输出流
            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("文件下载失败,请重试!");
        }
    }

    private static XSSFFont createBoldFont(XSSFWorkbook workbook) {
        XSSFFont font = workbook.createFont();
        font.setBold(true);
        font.setFontHeightInPoints((short) 12);
        return font;
    }

    //设置表头表格样式
    private static CellStyle getTitleCellStyle(XSSFWorkbook workbook) {
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setFont(createBoldFont(workbook));
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
        return cellStyle;
    }

    // 自动调整列宽和行高
    private static void autoAdjustRowHeight(XSSFSheet sheet, int rowCount) {
        for (int i = 0; i < rowCount; i++) {
            sheet.getRow(i).setHeightInPoints(25);
        }
    }

    //设置内容样式
    private static CellStyle getDataCellStyle(XSSFWorkbook workbook) {
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setDataFormat(workbook.createDataFormat().getFormat("#,##0.00"));
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
        cellStyle.setWrapText(true);
        return cellStyle;
    }

    //合并单元格
    public static void merge(List<Map<String, Object>> dataList, int[] mergeColumn, Sheet sheet) {

        Map<String, int[]> idToMinMax = new TreeMap<>();

        for (int i = 0; i < dataList.size(); i++) {
            Map<String, Object> rowData = dataList.get(i);
            //主表数据id相同的 合并指定列
            String id = String.valueOf(rowData.get("id"));
            //id相同的组成一个map  然后记录开始行 和结束行 作为合并的规则
            if (!idToMinMax.containsKey(id)) {
                idToMinMax.put(id, new int[]{i + 2, i + 2}); // 从第 3 行开始
            } else {
                int[] minMax = idToMinMax.get(id);
                minMax[1] = i + 2; // 更新最大行号
                idToMinMax.put(id, minMax);
            }
        }
        //根据map 合并指定列
        for (Map.Entry<String, int[]> entry : idToMinMax.entrySet()) {
            int[] minMax = entry.getValue();
            System.out.println(minMax[0] + " " + minMax[1]);
            if (minMax[0] == minMax[1]) {
                continue;
            }
            for (int i = 0; i < mergeColumn.length; i++) {

                sheet.addMergedRegion(new CellRangeAddress(minMax[0], minMax[1], mergeColumn[i] - 1, mergeColumn[i] - 1));
            }

        }
    }

    // 自动调整列宽
    private static void autoAdColumnWidth(XSSFSheet sheet, String[] columnTextArray) {
        int maxColumnCount = 0;
        for (String columnText : columnTextArray) {
            maxColumnCount = Math.max(maxColumnCount, columnText.length());
        }
        maxColumnCount = Math.max(maxColumnCount, 25); // 设置最小宽度为25个字符

        for (int i = 0; i < columnTextArray.length; i++) {
            sheet.setColumnWidth(i, maxColumnCount * 256); // 设置列宽
        }
    }

}
  
//需要合并的列在合并数组中 要合并的列 id值要相同才能合并
public void exportGroupStatement(DailyCondition dailyManagerDto, HttpServletResponse response) {
        if (dailyManagerDto.getId() != null && !dailyManagerDto.getId().isEmpty()) {
            String[] ids = dailyManagerDto.getId().split(",");
            dailyManagerDto.setIds(ids);
        }

        List dailyDetailExcelDtos = super.getJdbcBaseDao().queryForList("dailyManager.selectDailyDetailExcel", dailyManagerDto, DailyDetailExcelDto.class);
        String[] columnTextArray = {
                "序号",
                "人员",
                "日期",
                "逾期状态",
                "总工时",
                "工时单价",
                "点工工时",
                "工资总额",
                "计时金额",
                "备注",
                "协作人",
                "制造数量",
                "构件编码",
                "图号/标准号",
                "构件名称",
                "规格型号",
                "喷涂面积(㎡)",
                "构件单重(kg)",
                "总重(kg)",
                "工序单价",
                "计件金额",
                "计件工资分配",
                "制造工序",
                "产品分类",
                "制造类别",
                "项目名称",

        };
        String[] columnNames = {
                "row",
                "realName", "dailyDate", "overdueStatus", "totalHour", "workPrice", "workHour", "allPrice", "timePrice", "remark", "collaborators", "productNum",
                "cInvCode", "standardCode", "cInvName", "cInvStd", "sprayArea", "iInvWeight",
                "totalWeight", "numPrice", "pieceworkAmount", "pieceworkWageDistribution",
                "processName", "inventoryClassName",
                "methodName", "projectName"
        };

        int[] mergeColumn = {
                1, 2, 3, 4, 5, 6, 7, 8, 9, 10
        };
        exportService.exportMergeExcel("a报表", "a报表", response, dailyDetailExcelDtos, columnTextArray, columnNames, mergeColumn);
    }











 一般只支持两层的数据合并 , 不需要合并单元格 这个也能直接导出 功能还是蛮强大的

Java中可以使用POI库来实现Excel的导入操作。POI(Poor Obfuscation Implementation)是一个用Java编写的功能强大的开源库,可以用于读取、写入和操作Microsoft Office格式的文件,包括Excel文件。 首先,我们需要在项目中引入POI的相关依赖。可以通过在项目的pom.xml文件中添加以下依赖来实现: ``` <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> ``` 接下来,我们可以使用POI库中的类和方法来实现Excel文件的导入。例如,可以使用`XSSFWorkbook`类来读取.xlsx格式的Excel文件,使用`HSSFWorkbook`类来读取.xls格式的Excel文件。 首先,我们需要创建一个`File`对象,指定要读取的Excel文件的路径。然后,可以使用`Workbook`类的相关方法打开文件并读取数据。例如,可以使用`getSheetAt()`方法获取Excel中的工作表,使用`getRow()`方法获取行,使用`getCell()`方法获取单元格的值。 以下是一个简单的示例代码,演示如何使用POI库导入Excel文件并打印其中的内容: ``` import org.apache.poi.ss.usermodel.*; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class ExcelImporter { public static void main(String[] args) { try { File file = new File("path/to/excel.xlsx"); FileInputStream fis = new FileInputStream(file); Workbook workbook = WorkbookFactory.create(fis); Sheet sheet = workbook.getSheetAt(0); for (Row row : sheet) { for (Cell cell : row) { System.out.print(cell.toString() + "\t"); } System.out.println(); } fis.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 以上代码会读取Excel文件中第一个工作表的内容,并逐行打印。你可以根据实际需求进行进一步的数据处理或存储操作。 这就是使用Java的POI库实现Excel导入的简单示例。希望能对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值