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;
}
}
《行香子·归去来兮》
-- 北宋:辛弃疾
> 归去来兮,行乐休迟。命由天、富贵何时。
百年光景,七十者稀。奈一番愁,一番病,一番衰。
名利奔驰,宠辱惊疑。旧家时、都有些儿。
而今老矣,识破关机。算不如闲,不如醉,不如痴。