POI:操作Excel

Apache POI 工具包操作 Excel
测试用的版本是 3.16,目前版本最新为3.17。
2017年10月16日

大纲

  • POI 工具包简介
  • 导包
  • 核心类
  • 对象的创建
  • 读取Excel数据
  • 写出Excel文件
  • 格式化Excel style

#POI 工具包

JAVA中操作Excel的有两种比较主流的工具包: JXL 和 POI 。

  1. JXL 只能操作Excel 95、97、 2000也即以.xls为后缀的excel。
  2. POI 可以操作Excel 95及以后的版本,即可操作后缀为 .xls 和 .xlsx两种格式的excel。

#导包 点击下载 poi 3.16

  • commons-collections4-4.1.jar lib目录
  • log4j-1.2.17.jar lib目录
  • poi-3.16.jar
  • poi-ooxml-3.16.jar
  • poi-ooxml-schemas-3.16.jar
  • xmlbeans-2.6.0.jar ooxml-lib目录

#核心类

每个接口都有两个实现类,分别用于 07前 HSS 版本和 07和07后 XSS 版本的操作,类名只是 H 和 X 的区别,下面不再赘述。

HSSFWorkbook 07前版本 .xls
XSSFWorkbook 07和07后版本 .xlsx

  1. Workbook 接口 工作簿
  2. Sheet 接口 工作表
  3. Row 接口
  4. Cell 接口 单元格

#对象的创建

// 1. 创建工作簿对象
XSSFWorkbook workbook = new XSSFWorkbook();

// 2. 从工作簿对象创建工作表对象
XSSFSheet sheet = workbook.createSheet("成员表");

// 3. 从工作表对象创建行对象 从0开始
XSSFRow row = sheet.createRow(0);

// 4. 从行对象创建具体单元格对象 从0开始
XSSFCell cell = row.createCell(0);

层次结构

#读取Excel数据

这里用的是接口而非类,WorkbookFactory.create() 工厂方法会识别文件版本返回相应的子对象。这样避免两个版本两份代码的问题。

public void readExel() throws IOException {
    String fileName = "D:\\huangMP\\Desktop\\OutputExcelDemo.xls";
    FileInputStream fileInputStream = new FileInputStream(fileName);

    // 1. 创建工作簿
    Workbook workbook = WorkbookFactory.create(fileInputStream);

    // 2. 创建工作类
    Sheet sheet = workbook.getSheetAt(0);

    // 3. 创建行 , 第三行 注意:从0开始
    Row row = sheet.getRow(2);

    // 4. 创建单元格, 第三行第三列 注意:从0开始
    Cell cell = row.getCell(2);
    String cellString = getValue(cell);

    System.out.println("第三行第三列的值为 : " + cellString );

    workbook.close();
    fileInputStream.close();
}

POI 需要按照数据类型获取数据,如果类型错误会抛异常,这里我们将表格数据全用String类型获取。

// 把单元格数据以字符串形式输出
private String getString(Cell cell) {
    int cellType = cell.getCellType();

    switch (cellType) {
        case Cell.CELL_TYPE_STRING:
            return cell.getStringCellValue();
        case Cell.CELL_TYPE_BOOLEAN:
            return cell.getBooleanCellValue() + "";
        case Cell.CELL_TYPE_NUMERIC: {
            // 为了美观 去掉数值类型末尾的.0
            String value = cell.getNumericCellValue() + "";
            return (value.charAt(value.length() - 2) == '.' ? value.substring(0, value.length() - 2) : value);
        }
        default:
            return "";
    }
}

#输出Excel文件

public void outputExcel() throws IOException {
    // 1. 创建工作簿
    HSSFWorkbook workbook = new HSSFWorkbook();

    // 2. 创建工作类
    HSSFSheet sheet = workbook.createSheet("hello world");

    // 3. 创建行 , 第三行 注意:从0开始
    HSSFRow row = sheet.createRow(2);

    // 4. 创建单元格, 第三行第三列 注意:从0开始
    HSSFCell cell = row.createCell(2);
    cell.setCellValue("Hello World");

    String fileName = "D:\\huangMP\\Desktop\\OutputExcelDemo.xls";
    FileOutputStream fileOutputSteam = new FileOutputStream(fileName);

    workbook.write(fileOutputSteam);
    workbook.close();

    fileOutputSteam.close();
}

#格式化Excel style

##合并单元格

CellRanageAddress 类:单元格范围定义类

由 Sheet 类的 addMergedRegion() 方法添加进Excel。

// 合并单元格
/*
 * 单元格范围对象
 * 参1:起始行 0
 * 参2:结束行 1
 * 参3:起始列 0
 * 参4:结束列 1
 */
CellRangeAddress address = new CellRangeAddress(0, 1, 0, 1);
sheet.addMergedRegion(address);

起始行和起始列得到左上点 0.0
结束行和结束列得到右下点 1.1
包括的范围就是单元格合并的范围

##设置单元格样式

XSSFCellStyle 类:单元格样式类

由XSSFWorkBook 类的 createCellStyle();方法得到

单元格居中

XSSFCellStyle cellStyle = workbook.createCellStyle();
// 水平居中
cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
// 垂直居中
cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
...
// 给单元格设置样式
cell.setCellStyle(cellStyle);

单元格字体

HSSFFont 类:字体类

由XSSFWorkBook 类的 createFont();方法得到

XSSFFont font = workbook.createFont();
// 粗体
font.setBold(true);
// 字体
font.setFontName("黑体");
// 字体大小
font.setFontHeight(12);
...
// 给单元格样式对象添加字体样式
cellStyle.setFont(font);

行高列宽

行高 列宽
// 设置全局列宽
sheet.setDefaultColumnWidth(20 * 256);
// 设置全局行高
sheet.setDefaultRowHeightInPoints(30);

// 设置第 1 列的列宽
sheet.setColumnWidth(0, 20 * 256);
// 设置当前行的行高
row.setHeightInPoints(30);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容