Java中使用HSSFWorkbook生成excel

HSSFWorkbook 介绍


开发中经常会遇到 Excel 的处理,在 Java 中,操作 excel 目前有两个主流框架,分别是:

  • apache 的 poi

Apache POI [1] 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。

  • Java Excel

Java Excel是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容、创建新的Excel文件、更新已经存在的Excel文件。jxl 由于其小巧 易用的特点, 逐渐已经取代了 POI-excel的地位, 成为了越来越多的java开发人员生成excel文件的首选

这里提一下:HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls;XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx。对于不同版本的EXCEL文档要使用不同的工具类,如果使用错了,会提示如下错误信息:org.apache.poi.openxml4j.exceptions.InvalidOperationException,org.apache.poi.poifs.filesystem.OfficeXmlFileException

HSSFWorkbook 的使用


package com.knowledge.point;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Font;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: latinos-bub
 * @date: 2019/11/12 17:32
 * @description: 测试生成 excel
 * @className: com.knowledge.point.TestGenExcel
 */
public class TestGenExcel {

    public static void main(String[] args) throws Exception{

        // 创建一个 excel 工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();

        // 创建一个 excel 里面的 sheet 表格,并设置 sheet 名字
        HSSFSheet sheet = workbook.createSheet("测试生成 excel 表格是否乱码");

        // -------------------------------设置 工作簿的 样式 start--------------------------//
        HSSFCellStyle titleStyle  = workbook.createCellStyle(); // 创建标题样式
        titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);    // 设置标题水平居中显示
        titleStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 设置标题垂直居中显示
        HSSFFont titleFont = workbook.createFont();    // 创建标题字体
        titleFont.setItalic(false);                     // 设置字体为斜体字
        titleFont.setColor(Font.COLOR_RED);            // 将字体设置为“红色”
        titleFont.setFontHeightInPoints((short)16);    // 将字体大小设置为18px
        titleFont.setFontName("宋体");             // 将“宋体”字体应用到当前单元格上
        titleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);    //加粗
        titleStyle.setFont(titleFont); // 将 字体应用到 标题样式上

        HSSFCellStyle cellStyle  = workbook.createCellStyle();  // 创建 cell 单元格样式
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 设置 cell 单元格水平居中显示
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);  // 设置 cell 单元格垂直居中显示
        Font cellFont = workbook.createFont();  // 创建 单元格 字体
        cellFont.setFontHeightInPoints((short)10);    // 将字体大小设置为18px
        cellFont.setFontName("宋体");             // 字体应用到当前单元格上
        cellStyle.setFont(cellFont); // 将 字体应用到 单元格样式上
        // -------------------------------设置 工作簿的 样式 end--------------------------//



        // 创建 首行(即标题 行)
        HSSFRow headRow = sheet.createRow(0);
        // 创建 首行(即标题 行) 的 第一个单元格
        HSSFCell headCell = headRow.createCell(0);
        // 设置 首行(即标题 行)的文字内容
        headCell.setCellValue("更新时间");
        headCell.setCellStyle(titleStyle); // 设置 首行的 第一个单元格 样式
        // 创建 首行(即标题 行) 的 第二个单元格
        headCell = headRow.createCell(1);
        headCell.setCellValue("创建时间");
        headCell.setCellStyle(titleStyle);  // 这里一定要每次实例化之后都要设置样式
        headCell = headRow.createCell(2);
        headCell.setCellValue("删除状态");
        headCell.setCellStyle(titleStyle); // 这里一定要每次实例化之后都要设置样式
        headCell = headRow.createCell(3);
        headCell.setCellValue("id");
        headCell.setCellStyle(titleStyle); // 这里一定要每次实例化之后都要设置样式
        headCell = headRow.createCell(4);
        headCell.setCellValue("书名");
        headCell.setCellStyle(titleStyle); // 这里一定要每次实例化之后都要设置样式


        // 获取 模拟的 List<Map<String, Object> 数据
        List<Map<String, Object>> list = getList();

        for (int i = 0; i < list.size(); i++){  // 外层for是每一行的设置
            // 每一行(填充的内容行)时,我们都要新实例化一个 HSSRow 新行
            HSSFRow contentRow = sheet.createRow(sheet.getLastRowNum() + 1);    // 调用sheet的上次最后一行索引 + 1即可
            for (int j = 0; j < 5; j++){    // 内层 for 是 每行的 列数设置,因为我们的标题行有5列,所以这里设置5列
                // 每一行,我们都要在该行(即contentRow) 实例化 5 个 cell 单元格
                HSSFCell contentCell = contentRow.createCell(j);
                switch (j){ // 1,2,3,4,5个单元格分别写入自己正确的数据
                    case 0: // 每一行的第一列(即第一个cell)我们都写入 update_time 对应的数据,以下依次类推
                        contentCell.setCellValue(String.valueOf(list.get(i).get("update_time")));
                        break;
                    case 1:
                        contentCell.setCellValue(String.valueOf(list.get(i).get("create_time")));
                        break;
                    case 2:
                        contentCell.setCellValue(String.valueOf(list.get(i).get("delete_status")));
                        break;
                    case 3:
                        contentCell.setCellValue(String.valueOf(list.get(i).get("id")));
                        break;
                    case 4:
                        contentCell.setCellValue(String.valueOf(list.get(i).get("content")));
                        break;
                }
                // 设置 内容 居中显示 样式
                contentCell.setCellStyle(cellStyle);
            }
        }

        // 设置 列 的宽度
        sheet.setColumnWidth(0, 900 * 10);
        sheet.setColumnWidth(1, 900 * 10);
        sheet.setColumnWidth(2, 900 * 10);
        sheet.setColumnWidth(3, 900 * 10);
        sheet.setColumnWidth(4, 900 * 10);


        File xlsFile = new File("测试生成Excel.xls");
        workbook.write(new FileOutputStream(xlsFile));
        workbook.close();


        // 补充:如果是 web 程序,需要页面打开一个对话框,保存文件则,需要额外添加以下代码即可
        /*String fileName = "excel表";
        fileName = new String(fileName.getBytes(), "ISO-8859-1");
        HttpServletResponse response = this.getResponse().getHttpResponse();
        response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xls");
        response.setContentType("application/application/vnd.ms-excel;charset=utf-8");
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        // workbook 工作簿中写入数据
        workbook.write(byteArrayOutputStream);
        byte[] content = byteArrayOutputStream.toByteArray();
        InputStream inputStream = new ByteArrayInputStream(content);
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            byte[] b = new byte[2048];  // 设置 缓冲区的读取字节大小
            int i;
            while ((i = inputStream.read(b)) > 0) {
                out.write(b, 0, i);
            }
            out.flush();
        } catch (Exception e) {
            System.out.println("生成excel表格时出错: " + e.getMessage());
        } finally {
            if (inputStream != null)
                inputStream.close();
            if (out != null)
                out.close();
        }*/
    }




    /**
    * @Author latinos-bub
    * @Description //TODO   这里我先准备一个从别的地方获取的 sql 结果集合,以备下面写入数据使用
     * 这个 List 中我们就存放 12 个 Map 即可(模拟数据)
    * @Date 2019/11/12 21:17
    * @Param []
    * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
    **/
    private static List<Map<String, Object>> getList(){

        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map<String, Object> map1 = new HashMap<String, Object>();
        map1.put("update_time", "1569404166000");
        map1.put("create_time", "1569404122000");
        map1.put("delete_status", "1");
        map1.put("id", "2");
        map1.put("content", "如何削铁");
        list.add(map1);

        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("update_time", "1509357581000");
        map2.put("create_time", "1508893725000");
        map2.put("delete_status", "1");
        map2.put("id", "5");
        map2.put("content", "莎士比亚");
        list.add(map2);

        Map<String, Object> map3 = new HashMap<String, Object>();
        map3.put("update_time", "1510970055000");
        map3.put("create_time", "1508986168000");
        map3.put("delete_status", "1");
        map3.put("id", "6");
        map3.put("content", "亚里士多德");
        list.add(map3);


        Map<String, Object> map4 = new HashMap<String, Object>();
        map4.put("update_time", "1510118932000");
        map4.put("create_time", "1509001065000");
        map4.put("delete_status", "1");
        map4.put("id", "10");
        map4.put("content", "亚历山大");
        list.add(map4);


        Map<String, Object> map5 = new HashMap<String, Object>();
        map5.put("update_time", "1509002622000");
        map5.put("create_time", "1509002622000");
        map5.put("delete_status", "0");
        map5.put("id", "11");
        map5.put("content", "李白");
        list.add(map5);


        Map<String, Object> map6 = new HashMap<String, Object>();
        map6.put("update_time", "1569376168000");
        map6.put("create_time", "1569404290000");
        map6.put("delete_status", "1");
        map6.put("id", "12");
        map6.put("content", "无用是什么");
        list.add(map6);

        Map<String, Object> map7 = new HashMap<String, Object>();
        map7.put("update_time", "1569376160000");
        map7.put("create_time", "1569404290000");
        map7.put("delete_status", "0");
        map7.put("id", "13");
        map7.put("content", "选择吃什么饭是一件很痛苦的事");
        list.add(map7);

        Map<String, Object> map8 = new HashMap<String, Object>();
        map8.put("update_time", "1510983431000");
        map8.put("create_time", "1510983427000");
        map8.put("delete_status", "1");
        map8.put("id", "19");
        map8.put("content", "文章test2");
        list.add(map8);

        Map<String, Object> map9 = new HashMap<String, Object>();
        map9.put("update_time", "1569376164000");
        map9.put("create_time", "1569404290000");
        map9.put("delete_status", "1");
        map9.put("id", "20");
        map9.put("content", "就像选择在哪里睡觉一样");
        list.add(map9);

        Map<String, Object> map10 = new HashMap<String, Object>();
        map10.put("update_time", "1569376166000");
        map10.put("create_time", "1569404290000");
        map10.put("delete_status", "1");
        map10.put("id", "21");
        map10.put("content", "effective of java");
        list.add(map10);

        Map<String, Object> map11 = new HashMap<String, Object>();
        map11.put("update_time", "1569376172000");
        map11.put("create_time", "1569404290000");
        map11.put("delete_status", "1");
        map11.put("id", "22");
        map11.put("content", "荒岛求生");
        list.add(map11);

        Map<String, Object> map12 = new HashMap<String, Object>();
        map12.put("update_time", "1569376170000");
        map12.put("create_time", "1569404290000");
        map12.put("delete_status", "0");
        map12.put("id", "23");
        map12.put("content", "天使永远就在身边");
        list.add(map12);

        return list;
    }
}


《行香子·归去来兮》 -- 北宋:辛弃疾
> 归去来兮,行乐休迟。命由天、富贵何时。 百年光景,七十者稀。奈一番愁,一番病,一番衰。 名利奔驰,宠辱惊疑。旧家时、都有些儿。 而今老矣,识破关机。算不如闲,不如醉,不如痴。
posted @ 2022-06-22 00:26  LoremMoon  阅读(2005)  评论(0编辑  收藏  举报