Excel导出含二级表头

代码是学习此链接
代码大致流程如下(用的是POI):

1. 拿到所有表头放到二维数组,其中有一级表头的列:创建一维新数组,把一级放数组的[0],二级放数组的[1][2]这样的,内容放到list
2. 创建新的Excel,然后创建新的sheet
3. 创建title-按照所有表头创建第一行,若遇到二级的-正常创建,遇到一级表头(第一步中的一维数组),取出一维数组的第一个(即一级表头),并合并一级表头所占的列
4. 类似第三步,创建title-按照所有表头创建第一行,若遇到二级的-正常创建,遇到一级表头(第一步中的一维数组),取出一维数组的后面的(即二级表头),所有的列都是占一列,所以不合并列
5. 合并一二行中一样的标题,达到这样的效果(第4步是2.3行重复)

在这里插入图片描述

6. 把数据写入,也分二级和一级的情况

代码:


import com.iceolive.util.StringUtil;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;

import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: gongPing
 * ExportData迭代更新版本,增加了添加二级表头功能
 *传参1 String[][] headers {{一级表头,key},{一级表头,key},{一级表头,二级表头1,二级表头2...}}这里二级表头的key就是它的名称
 *传参2 title 标题 为空默认sheet
 *传参3 String[] mergeLine 要合并的列,这里是将指定的列全部合并
 *
 * 参考方法:/centerMeetingDayReport/excel
 * @Date: 2020/11/15 10:26
 */
public class ExportDataNew {
    private XSSFCellStyle headStyle;
    private SXSSFWorkbook workbook;
    private SXSSFSheet sheet;
    /**
     * 创建一行
     */
    private SXSSFRow row = null;
    private SXSSFCell cell = null;
    private int currentRow = 0;
    private XSSFCellStyle stringStyle;
    private String[][] headers;
    private String sheetName;
    private String sheetTitle;
    private Integer[] mergeLines;
    /**
     *
     * @param headers  表头列
     * @param title   标题
     * @param mergeLine  要合并单元格的列
     */
    public ExportDataNew(String[][] headers,String title,Integer[] mergeLine) throws FileNotFoundException {
        this.headers = headers;//表头
        if(StringUtil.isBlank(title)){
            this.sheetTitle ="sheet";
        }else{
            this.sheetTitle = title;
        }

        this.sheetName = "sheet1";
        this.mergeLines = mergeLine;
        try {
            workbook = new SXSSFWorkbook(1000);
            this.headStyle = (XSSFCellStyle) this.workbook.createCellStyle();
            //边框样式
            headStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
            headStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
            headStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
            headStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
            //前景填充颜色设置为有索引的颜色
            headStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex());
            headStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
            //对齐对样式
            headStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
            XSSFFont headFont = (XSSFFont) workbook.createFont();
            // 设置头部字体为宋体
            headFont.setFontName("宋体");
            // 粗体
            headFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
            headFont.setFontHeightInPoints((short) 11);
            // 单元格样式使用字体
            this.headStyle.setFont(headFont);

            createSheet(sheetName, headers,sheetTitle);
        } catch (Exception exc) {
            exc.printStackTrace();
        }

    }

    /**
     * 创建表头
     *
     * @param sheetName
     * @param headers
     */
    private void createSheet(String sheetName, String[][] headers,String sheetTitle) {
        sheet = (SXSSFSheet) workbook.createSheet(sheetName);
        //创建第一行表头
        row = (SXSSFRow) sheet.createRow(currentRow);
        int realLen = 0;
        int startLen = 0;
        cell = (SXSSFCell) row.createCell(realLen);
        //讲列设置为字符串类型
        cell.setCellType(XSSFCell.CELL_TYPE_STRING);
        //设置单元格背景颜色
        headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        cell.setCellStyle(headStyle);//设置样式
        cell.setCellValue(sheetTitle);//设置标题
        int titleLen = getTitleLen(headers);//总列数
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, titleLen-1)); // 合并单元格
        currentRow++;
        row = (SXSSFRow) sheet.createRow(currentRow);
        for (int i = 0; i < headers.length; i++) {
            String[] headerT = headers[i];
            if (headerT.length > 2) {
                //一级表头
                Integer len = headerT.length;
                for (int j = 0; j < len - 1; j++) {
                    cell = (SXSSFCell) row.createCell(realLen);
                    realLen++;
                    cell.setCellType(XSSFCell.CELL_TYPE_STRING);
                    cell.setCellStyle(headStyle);
                    cell.setCellValue(headers[i][0]);//设置一级表头(每次都从数组[0]里拿)
                }
                sheet.addMergedRegion(new CellRangeAddress(1, 1, startLen, realLen - 1)); // 合并一级表头需要的单元格
                startLen = realLen;//更新列到一级表头所占位置后对第一个

            } else {
                cell = (SXSSFCell) row.createCell(i);
                cell.setCellType(XSSFCell.CELL_TYPE_STRING);
                cell.setCellValue(headers[i][0]);
                cell.setCellStyle(headStyle);
                realLen++;
                startLen++;
            }

        }
        currentRow++;
        //创建第二行表头
        realLen = 0;
        row = (SXSSFRow) sheet.createRow(currentRow);
        for (int i = 0; i < headers.length; i++) {

            String[] headerT = headers[i];
            if (headerT.length > 2) {
                //二级表头
                Integer len = headerT.length;
                for (int j = 1; j < len; j++) {
                    String title = headerT[j];
                    cell = (SXSSFCell) row.createCell(realLen);
                    realLen++;
                    cell.setCellType(XSSFCell.CELL_TYPE_STRING);
                    cell.setCellStyle(headStyle);
                    cell.setCellValue(title);
                }

            } else {
                cell = (SXSSFCell) row.createCell(i);
                cell.setCellType(XSSFCell.CELL_TYPE_STRING);
                cell.setCellStyle(headStyle);
                cell.setCellValue("");
                //合并1-2行
                sheet.addMergedRegion(new CellRangeAddress(1, 2, i, i));
                realLen++;
            }
        }
        currentRow++;
    }

    /**
     * 获取表格宽度
     *
     * @param headers
     * @return
     */
    private int getTitleLen(String[][] headers) {
        int realLen = 0;
        for (int i = 0; i < headers.length; i++) {//length是总列数
            String[] headerT = headers[i];
            if (headerT.length > 2) {
                //一级表头
                Integer len = headerT.length;
                for (int j = 0; j < len - 1; j++) {
                    realLen++;
                }
            } else {
                realLen++;
            }
        }return realLen;

    }

    /**
     * 导出excel
     *
     * @param listRows
     * @throws ParseException
     */
    private void poiWriteExcelTo2007(List<Map<String, String>> listRows, OutputStream out)
            throws ParseException {
        for (int i = 0; i < listRows.size(); i++) {
            row = (SXSSFRow) sheet.createRow(currentRow);
            Map<String, String> listCells = listRows.get(i);
            int realLen=0;
            for (int j = 0; j < this.headers.length; j++) {
                String[] headerT=this.headers[j];
                if(headerT.length>2){
                    for(int k=1;k<headerT.length;k++){
                        String obj = listCells.get(headerT[k]) == null ? "" : String.valueOf(listCells.get(headerT[k]));
                        cell = (SXSSFCell) row.createCell(realLen);
                        realLen++;
                        cell.setCellValue(obj);
                        cell.setCellStyle(stringStyle);
                    }
                }else{
                    String obj = listCells.get(this.headers[j][1]) == null ? "" : String.valueOf(listCells.get(this.headers[j][1]));
                    cell = (SXSSFCell) row.createCell(j);
                    realLen++;
                    cell.setCellValue(obj);
                    cell.setCellStyle(stringStyle);
                }

            }
            currentRow++;
        }
        // sheet.addMergedRegion(new CellRangeAddress(3, 5, 0, 0)); // 合并单元格
        //合并列
        if(mergeLines!=null){
            System.out.println("合并列==========================");
            for(int  i=0 ;i<mergeLines.length;i++){
                int line= mergeLines[i];
                sheet.addMergedRegion(new CellRangeAddress(3, listRows.size()+2, line, line)); // 合并单元格
            }
        }

        try {
            workbook.write(out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 导出
     *
     * @throws IOException
     * @throws ParseException
     */
    public void exportData(List<Map<String, String>> listRows, OutputStream out)
            throws IOException, ParseException {
        ExportDataNew exportData = new ExportDataNew(this.headers,this.sheetTitle,this.mergeLines);
        exportData.poiWriteExcelTo2007(listRows, out);
    }



    /**
     * 导出
     *
     * @throws IOException
     * @throws ParseException
     */
    public void exportData(String fileName, List<Map<String, String>> listRows, HttpServletResponse response)
            throws IOException, ParseException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;Filename=" + new String(fileName.getBytes("gb2312"), "ISO8859-1"));
        exportData(listRows, response.getOutputStream());
    }



    public static void main(String[] args) throws IOException, ParseException {
        //定义一个对象数组!
        String[][] headers=new String[15][];
        headers[0]= new String[]{"日期", "DATE"};
        headers[1]= new String[]{"星期","DATE_STR"};
        headers[2]= new String[]{"时间","TIME"};
        headers[3]= new String[]{"会议室","NAME"};
        headers[4]= new String[]{"订会部门","RESERVE_DEPT_NAME"};
        headers[5]= new String[]{"订会人","MEETING_RESERVATION"};
        headers[6]= new String[]{"订会人电话","MOBILE"};
        headers[7]= new String[]{"会议名称","THEME"};
        headers[8]= new String[]{"参会领导","LEADERS"};
        headers[9]= new String[]{"会议等级","LEVELS"};
        headers[10]= new String[]{"会议人数","NUM"};
        headers[11]= new String[]{"预定是否符合流程","IS_TRUE"};
        //会议设备
        String[] eqment=new String[6];eqment[0]="会议设备";
        //会议物资
        String[] materials=new String[6];materials[0]="会议物资";
        //会议服务
        String[] server=new String[6];server[0]="会议服务";
        for(int i =0;i<5;i++){
            eqment[i+1]="测试服务A"+i+1;
            materials[i+1]="测试服务B"+i+1;
            server[i+1]="测试服务C"+i+1;
        }
        headers[12]= eqment;
        headers[13]= materials;
        headers[14]= server;
        //数据集合
        List<Map<String,String>> listMap =new ArrayList<Map<String,String>>();
        for (int i=0;i<5;i++){
            Map<String,String> map= new HashMap<String,String>();
            map.put("TIME","vo.getTime()");
            map.put("DATE","vo.getDate()");
            map.put("DATE_STR","vo.getDateStr()");
            map.put("IS_TRUE","vo.getIsTrue()");
            map.put("LEADERS","vo.getLeaders()");
            map.put("LEVELS","vo.getLevels()");
            map.put("MEETING_RESERVATION","vo.getMeetingReservation()");
            map.put("MOBILE","vo.getMobile()");
            map.put("THEME","vo.getTheme()");
            map.put("NUM","vo.getNum().toString()");
            map.put("RESERVE_DEPT_NAME","vo.getReserveDeptName()");
            map.put("NAME","vo.getName()");
            //二级表头数据赋值
            for(int j=0;j<eqment.length;j++){
                map.put(eqment[j],"1");
            }
            listMap.add(map);
        }

        //指定要合并的列,全部合并
        Integer[] mergeLine={0,1};
        OutputStream out = new FileOutputStream("/Users/zengxu/Desktop/临时/temp.xlsx");
        ExportDataNew exportDataNew = new ExportDataNew(headers,"接待中心每日会议汇总表",mergeLine);
        exportDataNew.exportData(listMap,out);
    }
}
Java导出Excel二级表头可以使用Apache POI库来实现。以下是一个简单的示例代码: ```java // 创建工作簿对象 Workbook workbook = new XSSFWorkbook(); // 创建工作表对象 Sheet sheet = workbook.createSheet("Sheet1"); // 创建第一行,作为一级表头 Row row1 = sheet.createRow(0); // 创建第一个单元格,作为一级表头第一列 Cell cell11 = row1.createCell(0); cell11.setCellValue("一级表头1"); // 合并一级表头第一列到第三列 CellRangeAddress region1 = new CellRangeAddress(0, 0, 0, 2); sheet.addMergedRegion(region1); // 创建第二个单元格,作为一级表头第四列 Cell cell12 = row1.createCell(3); cell12.setCellValue("一级表头2"); // 合并一级表头第四列到第六列 CellRangeAddress region2 = new CellRangeAddress(0, 0, 3, 5); sheet.addMergedRegion(region2); // 创建第三个单元格,作为一级表头第七列 Cell cell13 = row1.createCell(6); cell13.setCellValue("一级表头3"); // 合并一级表头第七列到第九列 CellRangeAddress region3 = new CellRangeAddress(0, 0, 6, 8); sheet.addMergedRegion(region3); // 创建第二行,作为二级表头 Row row2 = sheet.createRow(1); // 创建二级表头的单元格,根据一级表头的列数来创建 for (int i = 0; i < 9; i++) { Cell cell = row2.createCell(i); cell.setCellValue("二级表头" + (i+1)); } // 创建数据行 for (int i = 2; i < 10; i++) { Row row = sheet.createRow(i); // 创建数据单元格,根据一级表头的列数来创建 for (int j = 0; j < 9; j++) { Cell cell = row.createCell(j); cell.setCellValue("数据" + (i-1) + "-" + (j+1)); } } // 导出Excel文件 try (FileOutputStream outputStream = new FileOutputStream("example.xlsx")) { workbook.write(outputStream); } ``` 在上面的示例代码中,我们首先创建了一个工作簿对象和一个工作表对象。然后,我们创建了第一行作为一级表头,并使用`CellRangeAddress`类来合并单元格。接着,我们创建了第二行作为二级表头,并创建了数据行。最后,我们将工作簿对象导出Excel文件。 请注意,上面的示例代码使用了XSSFWorkbook类来创建工作簿对象,这是POI库中用于创建Excel 2007及以上版本文件的类。如果你要创建Excel 2003版本文件,可以使用HSSFWorkbook类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值