Apache POI是一个纯Java编写用来操作Microsoft Office的框架,最常见的应用是让服务器后台按照特定的数据生成Excel表格提供给用户实用。前段时间因为项目的需要被大量使用,使用以后的感觉是——低效而繁琐。也在网上找了不少别人的心得,但是感觉都写的过于复杂,因此结合客户的实际需求自己封装了几个实用的方法提供给真正有这方面需要的朋友参考。

首先,就Excel来说分为2007和2003两个版本,对应的后缀名为.xlsx和.xls。对此poi也提供了两套Workbook实现,分别为XSSFWorkbook和HSSFWorkbook。但是接口都是统一的,因此在使用的时候完全可以只针对接口编程。

其次,使用poi读取表格中的数据比较方便但是从数据库中读取数据再利用poi来生成就比较复杂。因此我推荐的做法是先利用Office设计好表格并保存成模板,再往模板里插入数据生成文件。

最后,工具类提供的静态方法均以Workbook为返回值,通常为了完成一次表格生成必须多次调用。如果是提供给客户下载只需要将response中的输出流交给Workbook即可,具体方法不再这里赘述。

/**
* Util提供的所有静态方法返回的对象都是Workbook,最后一步根据需求再做处理
* @author learnhow
*
*/
public class ExcelUtil {
public static final int Excel2003 = 0;
public static final int Excel2007 = 1; /**
* 根据版本号,获取Excel poi对象
*
* @param edition
* @param in
* @return
* @throws IOException
*/
public static Workbook getWorkbook(int edition, InputStream in) throws IOException {
if (edition == 0) {
return new HSSFWorkbook(in);
} else if (edition == 1) {
return new XSSFWorkbook(in);
}
return null;
} /**
* 从指定excel表格中逐行读取数据
*
* @param workbook
* @param startRow
* @param startCol
* @param indexSheet
* @return
*/
public static List<List<String>> getExcelString(Workbook workbook, int startRow, int startCol, int indexSheet) {
List<List<String>> stringTable = new ArrayList<List<String>>();
// 获取指定表对象
Sheet sheet = workbook.getSheetAt(indexSheet);
// 获取最大行数
int rowNum = sheet.getLastRowNum();
for (int i = startRow; i <= rowNum; i++) {
List<String> oneRow = new ArrayList<String>();
Row row = sheet.getRow(i);
// 根据当前指针所在行数计算最大列数
int colNum = row.getLastCellNum();
for (int j = startCol; j <= colNum; j++) {
// 确定当前单元格
Cell cell = row.getCell(j);
String cellValue = null;
if (cell != null) {
// 验证每一个单元格的类型
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
// 表格中返回的数字类型是科学计数法因此不能直接转换成字符串格式
cellValue = new BigDecimal(cell.getNumericCellValue()).toPlainString();
break;
case Cell.CELL_TYPE_STRING:
cellValue = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_FORMULA:
cellValue = new BigDecimal(cell.getNumericCellValue()).toPlainString();
break;
case Cell.CELL_TYPE_BLANK:
cellValue = "";
break;
case Cell.CELL_TYPE_BOOLEAN:
cellValue = Boolean.toString(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_ERROR:
cellValue = "ERROR";
break;
default:
cellValue = "UNDEFINE";
}
} else {
cellValue = "";
}
// 生成一行数据
oneRow.add(cellValue);
}
stringTable.add(oneRow);
}
return stringTable;
} /**
* 根据给定的数据直接生成workbook
*
* @param workbook
* @param sheetName
* @param data
* @return
*/
public static Workbook createExcel(Workbook workbook, String sheetName, List<List<String>> data) {
Sheet sheet = workbook.createSheet(sheetName);
for (int i = 0; i < data.size(); i++) {
List<String> oneRow = data.get(i);
Row row = sheet.createRow(i);
for (int j = 0; j < oneRow.size(); j++) {
Cell cell = row.createCell(j);
cell.setCellValue(oneRow.get(j));
}
}
return workbook;
} /**
* 往指定的sheet表中插入数据,插入的方法是提供一组valueMap。int[]是2维数组代表需要插入的数据坐标,从0开始
*
* @param workbook
* @param sheetIndex
* @param valueMap
* @return
*/
public static Workbook insertExcel(Workbook workbook, int sheetIndex, Map<int[], String> valueMap) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
Iterator<Entry<int[], String>> it = valueMap.entrySet().iterator();
while (it.hasNext()) {
Entry<int[], String> cellEntry = it.next();
int x = cellEntry.getKey()[0];
int y = cellEntry.getKey()[1];
String value = cellEntry.getValue();
Row row = sheet.getRow(y);
Cell cell = row.getCell(x);
cell.setCellValue(value);
}
return workbook;
} /**
* 设置指定行的行高
*
* @param workbook
* @param rowHeight
* @param sheetIndex
* @param rowIndex
* @return
*/
public static Workbook setRowHeight(Workbook workbook, int rowHight, int sheetIndex, int rowIndex) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
Row row = sheet.getRow(rowIndex);
row.setHeight((short) rowHight);
return workbook;
} /**
* 设置列宽
*
* @param workbook
* @param columnWidth
* @param sheetIndex
* @param columnIndex
* @return
*/
public static Workbook setColumnWidth(Workbook workbook, int columnWidth, int sheetIndex, int columnIndex) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
sheet.setColumnWidth(columnIndex, columnWidth);
return workbook;
} /**
* 删除指定行
*
* @param workbook
* @param sheetIndex
* @param rowIndex
* @return
*/
public static Workbook removeRow(Workbook workbook, int sheetIndex, int rowIndex) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
int lastRowNum = sheet.getLastRowNum();
if (rowIndex >= 0 && rowIndex < lastRowNum) {
sheet.shiftRows(rowIndex + 1, lastRowNum, -1);
}
if (rowIndex == lastRowNum) {
sheet.removeRow(sheet.getRow(rowIndex));
}
return workbook;
} /**
* 在指定位置插入空白行
*
* @param workbook
* @param sheetIndex
* @param rowIndex
* @return
*/
public static Workbook insertBlankRow(Workbook workbook, int sheetIndex, int rowIndex) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
int lastRowNum = sheet.getLastRowNum();
if (rowIndex >= 0 && rowIndex <= lastRowNum) {
sheet.shiftRows(rowIndex, lastRowNum, 1);
// 获得上一行的Row对象
Row preRow = sheet.getRow(rowIndex - 1);
short rowNum = preRow.getLastCellNum();
Row curRow = sheet.createRow(rowIndex);
// 新生成的Row创建与上一个行相同风格的Cell
for (short i = preRow.getFirstCellNum(); i < rowNum; i++) {
Cell cell = preRow.getCell(i);
CellStyle style = cell.getCellStyle();
curRow.createCell(i).setCellStyle(style);
}
return workbook;
}
return null;
} /**
* 根据sheet(0)作为模板重建workbook
*
* @param workbook
* @param sheetNum
* @param sheetNames
* @return
*/
public static Workbook rebuildWorkbook(Workbook workbook, int sheetNum, String... sheetNames) {
if(sheetNames.length == sheetNum){
for (int i = 0; i < sheetNum; i++) {
workbook.cloneSheet(0);
// 生成后面的工作表并指定表名
workbook.setSheetName(i + 1, sheetNames[i]);
}
// 删除第一张工作表
workbook.removeSheetAt(0);
return workbook;
}
return null;
}
}

简单使用Apache POI的更多相关文章

  1. 利用Apache POI 实现简单的Excel表格导出

    1.利用POI API实现简单的Excel表格导出 首先假设一个学生实体类: package com.sun.poi.domain; import java.io.Serializable; impo ...

  2. apache poi导出excel报表

    Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能.POI为"P ...

  3. APACHE POI教程 --java应用程序用POI与Excel交互

    POI报表 --用POI与Excel交互 AURISOFT 第一章 POI简介 --Jakata Poi HSSF:纯java的Excel解决方案 在我们实际的开发中,表现层的解决方案虽然有多样,但是 ...

  4. 如何用Apache POI操作Excel文件-----如何在已有的Excel文件中插入一行新的数据?

    在POI的第一节入门中,我们提供了两个简单的例子,一个是如何用Apache POI新建一个工作薄,另外一个例子是,如果用Apache POI新建一个工作表.那么在这个章节里面,我将会给大家演示一下,如 ...

  5. Apache POI使用详解

    Apache POI使用详解 1.POI结构与常用类 (1)POI介绍 Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案 ...

  6. Apache POI组件操作Excel,制作报表(一)

    Apache的POI组件是Java操作Microsoft Office办公套件的强大API,其中对Word,Excel和PowperPoint都有支持,当然使用较多的还是Excel,因为Word和Po ...

  7. 解决 apache poi 转换 word(docx) 文件到 html 文件表格没边框的问题

    一.起因 这几天在做电子签章问题,要通过替换docx文件中的占位符生成包含业务数据的合同数据,再转换成html文件,转换成pdf文件.遇到的问题是:通过apache poi转换docx到html时,原 ...

  8. Java中用Apache POI生成excel和word文档

    概述: 近期在做项目的过程中遇到了excel的数据导出和word的图文表报告的导出功能.最后决定用Apache POI来完毕该项功能.本文就项目实现过程中的一些思路与代码与大家共享.同一时候.也作为自 ...

  9. 4.Apache POI使用详解

    一.POI结构与常用类 1.POI介绍 Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案读和写的功能. .NET的开发人 ...

随机推荐

  1. Java实现Oracle数据库备份

    今天将很早就实现的一个Oracle数据库备份功能粘贴出来,这个功能是在大学做阶段设计时写的: import java.io.File; import java.io.IOException; /** ...

  2. C#转摘

    尽量用Func和lambda解决函数变量问题,用var, dynamic来解决动态变量问题

  3. Linux下安装性能测试负载机LG

    系统:CentOS release 6.6 (Final)  x86_64 安装包: 1.LRLG_00031.iso [Load Generator Standalone (Linux 64-bit ...

  4. java基础总结——开篇

    工作三年多了,一直没时间静下心来好好总结,2016年马上就要过去了.也算是给自己在新一年的一个任务吧!总结java基础,然后再总结javaweb.纯属个人学习总结,总结过程中如有模糊的地方,望各位看官 ...

  5. iOS索引列开发详解

    做苹果开发的朋友在地区列表可能会遇到在页面的右侧有一列类似与导航的索引列,这次有机会遇到了,细细研究了一下,原来没有想象中的困难,只需要简单的几步就能做出自己的索引列.本来想和搜索条在一块讲解,后来考 ...

  6. iOS 因为reason: 'Pushing the same view controller instance more than once is not supported而奔溃(上)

    这个问题是什么意思呢,之前遇到过几次,但程序再次打开时没有问题,也就没有重视,今天又遇到了,无法忍受啊. 控制台报的错误是:"不支持多次推入相同的视图控制器实例". 什么原因造成的 ...

  7. App Extension

    一.扩展概述 扩展(Extension)是iOS 8中引入的一个非常重要的新特性.扩展让app之间的数据交互成为可能.用户可以在app中使用其他应用提供的功能,而无需离开当前的应用. 在iOS 8系统 ...

  8. 2017年8个UI设计流行趋势

    设计趋势变化的理由需要考虑各种各样的因素.让我们来一起看看2017年的设计流行趋势吧. 应用界面的设计趋势是不断变化的.随着时间的推移他也在不断的成长,进化.虽然有些趋势还有待检验,但我们还是需要不断 ...

  9. php代码性能分析方法

    1.用到的函数 microtime() ,函数返回当前 Unix 时间戳和微秒数,本函数以 "msec sec" 的格式返回一个字符串,其中 sec 是自 Unix 纪元(0:00 ...

  10. 2.C语言中的关键字

    1.auto 修饰局部变量,编译器默认所有局部变量都是用auto来修饰的,所以在程序中很少见到. 2.static 它作用可大了,除了可以修饰变量,还可以修饰函数,修饰变量,改变其作用域和生命周期,修 ...