Java POI的Excel操作(行高列宽比例;生成说明,标题,字段;导出Excel代码,压缩)

摘要

本文主要讲解了POI中的表格行高列宽比例,以及根据这个不同的场景生成,如标题,说明,字段头。主要是思路给大家参考,生成表格如下(完整代码代码在最后,由于我的数据格式特殊,我把我以前的通用导出数据代码放在了数据行导出

目录

目录

摘要

比例讲解

行高

列宽

代码

生成填写说明

生成标题行

生成字段头

数据行导出

整代码

CategoryDataVo 类 


比例讲解

行高

行高的设置方法常用的是 

row.setHeight (heght) 

他们之间的比例近似于1:20,例如,Excel中的50磅(100像素),代码中应该写为

row.setHeight((short) (50*20));

列宽

列宽的设置方法为

sheet.setColumnWidth(cellNum, weight);

 他们之间的公式大致为(weight+0.7)*256,例如,Excel中的50磅(100像素),代码中应该写为

 sheet.setColumnWidth(cellNum, (int) ((50 + 0.72) * 256));

代码

生成填写说明

他的行高调整  noteDatas.size() * (30*20) //说明总行数*(单行高度*比例)

    /**
     * 生成第一行数据(填写说明)
     * @param regionNumber      合并单元格个数
     * @param noteDatas         说明数据
     * @param workbook          工作薄
     * @param sheet             sheet
     * @autor whhhh
     */
    private static void addDetailRow(Integer regionNumber, List<String> noteDatas, HSSFWorkbook workbook, HSSFSheet sheet) {
        // 创建提示行(第一行)
        HSSFRow rowDetail = sheet.createRow(0);

        //转换成字符串
        StringBuilder noted= new StringBuilder();
        int keyNum=1;

        //遍历添加每一行加序号 \r\n用来换行
        for(String fileNote:noteDatas){
            noted.append(keyNum).append(". ").append(fileNote).append("\r\n");
            keyNum++;
        }

        //生成表格数据
        HSSFRichTextString ts = new HSSFRichTextString("填写说明\r\n"+noted);

        //设置部分字体加粗
        HSSFFont noteFont = workbook.createFont();
        noteFont.setBold(true);
        noteFont.setFontHeightInPoints((short) 14);
        ts.applyFont(0, 4, noteFont);

        //添加内容
        rowDetail.createCell(0).setCellValue(ts);

        //设置标题字体样式
        HSSFCellStyle detailStyle = workbook.createCellStyle();
        detailStyle.setAlignment(HorizontalAlignment.LEFT);//水平居左
        detailStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        HSSFFont detailFont = workbook.createFont();
        detailFont.setFontName("宋体");//字体
        detailFont.setFontHeightInPoints((short) 12);//字体大小
        detailStyle.setFont(detailFont);
        detailStyle.setWrapText(true);

        //合并单元格
        CellRangeAddress region1 = new CellRangeAddress(0, 0, 0, regionNumber);
        sheet.addMergedRegion(region1);

        //设置当前行样式
        rowDetail.getCell(0).setCellStyle(detailStyle);//把样式加入该行
        short detailHeight= (short) (noteDatas.size() * (30*20));//说明行数*(单行高度*比例)
        rowDetail.setHeight(detailHeight);//设置行高
    }

生成标题行

    /**
     * 生成第二行数据(文件标题)
     * @param reginNumber    所占单元格个数
     * @param title         标题
     * @param workbook      工作薄
     * @param sheet         sheet
     * @autor whhhh
     */
    private static void addTitleRow(Integer reginNumber,String title, HSSFWorkbook workbook, HSSFSheet sheet) {
        // 创建标题行(第二行)存入标题
        HSSFRow rowTitle = sheet.createRow(1);
        rowTitle.createCell(0).setCellValue(title);
        //设置标题字体样式
        HSSFCellStyle titleStyle = workbook.createCellStyle();
        titleStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        HSSFFont titleFont = workbook.createFont();
        titleFont.setFontName("方正小标宋_GBK");//字体
        titleFont.setFontHeightInPoints((short) 22);//字体大小
        titleStyle.setFont(titleFont);
        rowTitle.getCell(0).setCellStyle(titleStyle);
        rowTitle.setHeight((short) (50*20));
        //合并单元格
        CellRangeAddress region2 = new CellRangeAddress(1, 1, 0, reginNumber);
        sheet.addMergedRegion(region2);
    }

生成字段头

    /**
     * 生成第三行数据(表头)
     * @param excelHeads    表头
     * @param workbook      工作薄
     * @param sheet         sheet
     * @autor whhhh
     */
    private static void addExcelHead(List<String> excelHeads, HSSFWorkbook workbook, HSSFSheet sheet) {
        //创建表头(第三行)
        HSSFRow row = sheet.createRow(2);
        //定义循环变量
        int cellNum=1;
        //设置字段头字体样式
        HSSFCellStyle headStyle = workbook.createCellStyle();
        HSSFFont headFont = workbook.createFont();
        headFont.setFontName("黑体");
        headFont.setFontHeightInPoints((short) 13);
        headStyle.setFont(headFont);
        headStyle.setAlignment(HorizontalAlignment.CENTER);

        //生成序号列 并设置样式
        row.createCell(0).setCellValue("序号");
        row.getCell(0).setCellStyle(headStyle);
        //生成表头数据并设置样式
        for (String excelHead:excelHeads) {
            row.createCell(cellNum).setCellValue(excelHead);
            row.getCell(cellNum).setCellStyle(headStyle);
            //设置表格单元格长度
            if(excelHead.contains("地址")) {
                //地址栏内容一般偏多,设置稍大点
                sheet.setColumnWidth(cellNum, (int) ((50 + 0.71) * 256));
            }else {
                sheet.setColumnWidth(cellNum, (int) ((20 + 0.71) * 256));
            }
            cellNum++;
        }
    }

数据行导出

由于我的数据行格式特殊,我把我以前的导出数据放在这里

/**
     * 输出Excel
     * @param dataList 数据集合
     * @param resp  响应
     * @throws CustomerException 自定义异常
     * @throws IOException  io异常
     * @Auther: whhh
     * @Date: 2021/4/15 11:44
     */
    public static void exportList(List<Map<String,Object>> dataList, HttpServletResponse resp,String fileName) throws CustomerException, IOException {

        if (CollectionUtils.isEmpty(dataList)){
            return;
        }

        //2.创建XSSFWorkbook
        XSSFWorkbook workbook=new XSSFWorkbook();

        //3.创建sheet对象
        XSSFSheet sheet = workbook.createSheet();

        //4.创建表头
        XSSFRow row=sheet.createRow(0);

        int m=0;   //定义循环变量
        //写入表头数据
        for(String key:dataList.get(0).keySet()){
            row.createCell(m).setCellValue(key);
            m++;
        }

        //遍历集合,填充每一行的数据
        for(int i=0;i< dataList.size();i++){
            m=0; //重置循环变量

            //获取当前数据行
            Map<String,Object> data=dataList.get(i);
            //创建当前行
            XSSFRow r = sheet.createRow(i+1);

            //存储数据
            for(String key:data.keySet()){
                r.createCell(m).setCellValue(data.get(key).toString());
                m++;
            }
        }

        fileName=UUID.randomUUID()+".xlsx";
        //6.告诉浏览器以下载的方式打开
        resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));
        //7.把数据写出到浏览器
        OutputStream out = resp.getOutputStream();
        workbook.write(out);
    }

由于我的数据行格式特殊,我把我以前的导出数据放上面 ↑↑↑↑

整代码

由于我的数据行格式特殊,我把我以前的导出数据代码放上面 ↑↑↑↑

我这里是生成一个目录,里面放了一张excel和图片进行压缩

private void downloadZip(HttpServletResponse resp, List<Map<String, Object>> records, List<String> excelHeads, List<Integer> excelHeadsIds, CategoryDataVo categoryDataVo) {
        try {
            SimpleDateFormat df=new SimpleDateFormat("yyyyMMdd");
            //在当前目录生成根文件夹
            File temDir = new File(categoryDataVo.getFileName() + df.format(new Date()));
            if (!temDir.exists()) {
                temDir.mkdirs();
            }
            String zipName = categoryDataVo.getFileName() + ".zip";
            //生成表格
            downloadExcel(records, excelHeads, excelHeadsIds, temDir,categoryDataVo);

            //告诉浏览器以下载的方式打开zip
            resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipName, "UTF-8"));
            resp.setContentType("application/zip");
            //压缩文件
            ZipFilesUtil.toZip(temDir.getPath(), resp.getOutputStream(),true);
            temDir.delete();
        }catch (CustomerException e){
            e.printStackTrace();
            throw new CustomerException(MessageCode.IMAGE_DOWNLOAD_FAIL);
        }catch (Exception e){
            e.printStackTrace();
            throw new CustomerException(MessageCode.EXCEL_DOWNLOAD_FAIL);
        }
    }    


    /**
     * 导出数据表格
     * @param data 数据
     * @param excelHeads 数据字段头
     * @param excelHeadIds 数据字段头id
     * @param temDir 根目录
     * @param categoryDataVo 分类提示 代码在最后
     * @autor whhhh
     */
    public static void downloadExcel(List<Map<String, Object>> data, List<String> excelHeads, List<Integer> excelHeadIds,File temDir,CategoryDataVo categoryDataVo) {

        try {
            //生成excel文件
            String excelName="/"+categoryDataVo.getFileName()+".xls";
            File excel = new File(temDir + excelName);

            //创建Workbook和Sheet文档
            HSSFWorkbook workbook = new HSSFWorkbook();
            HSSFSheet sheet = workbook.createSheet("sheet1");

            // 创建提示行(第一行)
            addDetailRow(excelHeads.size(), categoryDataVo.getNoteDatas(), workbook, sheet);

            // 创建标题行(第二行)存入数据
            addTitleRow(excelHeads.size(), categoryDataVo.getFileName(), workbook, sheet);

            //创建表头(第三行)
            addExcelHead(excelHeads, workbook, sheet);

            //定义单元格循环变量
            int cellNum;
            //这里的数据行第四行起
            int rowNum=3;
            //设置数据样式
            HSSFCellStyle cellStyle=workbook.createCellStyle();
            cellStyle.setWrapText(true);//自动换行
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            //添加数据行字体
            HSSFFont cellFont = workbook.createFont();
            cellFont.setFontName("宋体");//字体
            cellFont.setFontHeightInPoints((short) 11);
            cellStyle.setFont(cellFont);
            //获取数据
            for (Map<String, Object> map:data) {

                //取出当前行数据
                JSONObject extData = (JSONObject) map.get("extData");
//                JSONArray images = (JSONArray) extData.get("images");
                if (extData!=null){
                    cellNum=1;
                    //创建数据行
                    HSSFRow dataRow = sheet.createRow(rowNum);
                    dataRow.createCell(0).setCellValue(rowNum-2);
                    dataRow.getCell(0).setCellStyle(cellStyle);
                    for (Integer id:excelHeadIds) {
                        //取出数据
                        if(extData.get(id.toString())!=null) {
                            String rowdata = extData.get(id.toString()).toString();
                            if(rowdata!=null){
                                dataRow.createCell(cellNum).setCellValue(rowdata);
                                dataRow.getCell(cellNum).setCellStyle(cellStyle);
                            }
                        }
                       cellNum++;
                    }
                    rowNum++;
                }
            }
            //把表格数据写出到目录路径
            FileOutputStream excelOut = new FileOutputStream(excel);
            workbook.write(excelOut);
            excelOut.close();
        }catch (CustomerException e){
            e.printStackTrace();
            throw new CustomerException(MessageCode.IMAGE_DOWNLOAD_FAIL);
        }catch (Exception e){
            e.printStackTrace();
            throw new CustomerException(MessageCode.EXCEL_DOWNLOAD_FAIL);
        }

    }




    /**
     * 生成第一行数据(填写说明)
     * @param regionNumber      合并单元格个数
     * @param noteDatas         说明数据
     * @param workbook          工作薄
     * @param sheet             sheet
     * @autor whhhh
     */
    private static void addDetailRow(Integer regionNumber, List<FileNote> noteDatas, HSSFWorkbook workbook, HSSFSheet sheet) {
        // 创建提示行(第一行)
        HSSFRow rowDetail = sheet.createRow(0);

        //转换成字符串
        StringBuilder noted= new StringBuilder();
        int keyNum=1;
        //遍历添加每一行加序号
        for(FileNote fileNote:noteDatas){
            noted.append(keyNum).append(". ").append(fileNote.getData()).append("\r\n");
            keyNum++;
        }
        //生成表格数据
        HSSFRichTextString ts = new HSSFRichTextString("填写说明\r\n"+noted);
        //设置部分字体加粗
        HSSFFont noteFont = workbook.createFont();
        noteFont.setBold(true);
        noteFont.setFontHeightInPoints((short) 14);
        ts.applyFont(0, 4, noteFont);
        //添加内容
        rowDetail.createCell(0).setCellValue(ts);
        //设置标题字体样式
        HSSFCellStyle detailStyle = workbook.createCellStyle();
        detailStyle.setAlignment(HorizontalAlignment.LEFT);//水平居左
        detailStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        HSSFFont detailFont = workbook.createFont();
        detailFont.setFontName("宋体");//字体
        detailFont.setFontHeightInPoints((short) 12);//字体大小
        detailStyle.setFont(detailFont);
        detailStyle.setWrapText(true);
        //合并单元格
        CellRangeAddress region1 = new CellRangeAddress(0, 0, 0, regionNumber);
        sheet.addMergedRegion(region1);
        rowDetail.getCell(0).setCellStyle(detailStyle);//把样式加入该行
        short detailHeight= (short) (noteDatas.size() * (20*20));//说明行数*(单行高度*比例)
        rowDetail.setHeight(detailHeight);//设置行高
    }






    /**
     * 生成第二行数据(文件标题)
     * @param reginNumber    所占单元格个数
     * @param title         标题
     * @param workbook      工作薄
     * @param sheet         sheet
     * @autor whhhh
     */
    private static void addTitleRow(Integer reginNumber,String title, HSSFWorkbook workbook, HSSFSheet sheet) {
        // 创建标题行(第二行)存入标题
        HSSFRow rowTitle = sheet.createRow(1);
        rowTitle.createCell(0).setCellValue(title);
        //设置标题字体样式
        HSSFCellStyle titleStyle = workbook.createCellStyle();
        titleStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        HSSFFont titleFont = workbook.createFont();
        titleFont.setFontName("方正小标宋_GBK");//字体
        titleFont.setFontHeightInPoints((short) 22);//字体大小
        titleStyle.setFont(titleFont);
        rowTitle.getCell(0).setCellStyle(titleStyle);
        rowTitle.setHeight((short) (50*20));
        //合并单元格
        CellRangeAddress region2 = new CellRangeAddress(1, 1, 0, reginNumber);
        sheet.addMergedRegion(region2);
    }




    /**
     * 生成第三行数据(表头)
     * @param excelHeads    表头
     * @param workbook      工作薄
     * @param sheet         sheet
     * @autor whhhh
     */
    private static void addExcelHead(List<String> excelHeads, HSSFWorkbook workbook, HSSFSheet sheet) {
        //创建表头(第三行)
        HSSFRow row = sheet.createRow(2);
        //定义循环变量
        int cellNum=1;
        //设置字段头字体样式
        HSSFCellStyle headStyle = workbook.createCellStyle();
        HSSFFont headFont = workbook.createFont();
        headFont.setFontName("黑体");
        headFont.setFontHeightInPoints((short) 13);
        headStyle.setFont(headFont);
        headStyle.setAlignment(HorizontalAlignment.CENTER);

        //生成序号列 并设置样式
        row.createCell(0).setCellValue("序号");
        row.getCell(0).setCellStyle(headStyle);
        //生成表头数据并设置样式
        for (String excelHead:excelHeads) {
            row.createCell(cellNum).setCellValue(excelHead);
            row.getCell(cellNum).setCellStyle(headStyle);
            //设置表格单元格长度
            if(excelHead.contains("地址")) {
                //地址栏内容一般偏多,设置稍大点
                sheet.setColumnWidth(cellNum, (int) ((50 + 0.71) * 256));
            }else {
                sheet.setColumnWidth(cellNum, (int) ((20 + 0.71) * 256));
            }
            cellNum++;
        }
    }

CategoryDataVo 类 

package com.glzt.standingBookManagement.dto.vo;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.glzt.standingBookManagement.dao.FileNoteDao;
import com.glzt.standingBookManagement.dto.entity.FileNote;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @Auther: whhh
 * @Date: 2021/5/13 17:58
 * @Description:
 */
@Data
public class CategoryDataVo {

    @Autowired
    private FileNoteDao fileNoteDao;

    public static final String SPECIAL= "成都市大气污染防控专项督查工作问题台账";
    public static final String MUNICIPAL= "成都大气污染防控专项督查工作市级部门自查台账";
    public static final String COUNTY= "成都大气污染防控专项督查工作区县自查台账";

    private String fileName;
    private List<FileNote> noteDatas;


}

 

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值