之前使用poi导出excel,每次都是使用API去一步步画出excel的样式,这种方法在遇到复杂的excel需求时,会浪费很多时间。后来决定尝试使用模板的方法进行导出,这样只需要关心要导出的数据即可,节省了很多时间。下面的代码封装了一些简单的API,包含了03和07格式的导出, 能满足基本需求,贴出来跟大家分享下,有兴趣的同学也可以在此基础上扩展,和大家共享。
代码已经分享到git@osc上啦,地址:http://git.oschina.net/carpo/carpo/tree/master/carpo.xls
使用方法
- jar包依赖
poi-3.8-beta4-20110826.jar
poi-ooxml-3.8-beta4.jar
poi-ooxml-schemas-3.8-beta4.jar
xmlbeans-2.6.0.jar
- 源码
1.ExcelExp为抽象基类,定义了基本操作方法
package com.example;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
*
* excel模板导出基类
* @since jdk1.6
* @date 2016-6-2
*
*/
public abstract class ExcelExp {
protected XSSFWorkbook xssWb;
protected XSSFSheet xssSheet;
protected HSSFWorkbook hssWb;
protected HSSFSheet hssSheet;
/**
* 设置页脚
*/
public abstract void createFooter();
/**
*
* 插入行
* @param startRow
* @param rows
*/
public abstract void insertRows(int startRow, int rows);
/**
*
* 替换模板中变量
* @param map
*/
public abstract void replaceExcelData(Map<String, String> map);
/**
* 下载excel
* @param response
* @param filaName
* @throws IOException
*/
public abstract void downloadExcel(HttpServletResponse response, String filaName) throws IOException;
public XSSFWorkbook getXssWb() {
return xssWb;
}
public void setXssWb(XSSFWorkbook xssWb) {
this.xssWb = xssWb;
}
public XSSFSheet getXssSheet() {
return xssSheet;
}
public void setXssSheet(XSSFSheet xssSheet) {
this.xssSheet = xssSheet;
}
public HSSFWorkbook getHssWb() {
return hssWb;
}
public void setHssWb(HSSFWorkbook hssWb) {
this.hssWb = hssWb;
}
public HSSFSheet getHssSheet() {
return hssSheet;
}
public void setHssSheet(HSSFSheet hssSheet) {
this.hssSheet = hssSheet;
}
}
2.XssExcelExp为07格式(.xlsx)的实现类
package com.example;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFFooter;
import org.apache.poi.ss.usermodel.Footer;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
*
* excel导出类
* <p>处理.xlsx格式<p>
* @since jdk1.6
* @date 2016-6-2
*
*/
public class XssExcelExp extends ExcelExp{
public XssExcelExp() {
super();
}
/**
* 构造函数
* ExcelExp
* @param filePath 文件路径,如com/test/template/test.xlsx
* @param sheetNum 要操作的页签,0为第一个页签
* @throws IOException
*/
public XssExcelExp(String filePath, int sheetNum) throws IOException {
URL resource = this.getClass().getClassLoader().getResource(filePath);
InputStream is = new FileInputStream(resource.getFile());
xssWb = new XSSFWorkbook(is);
xssSheet = xssWb.getSheetAt(sheetNum);
}
/**
* 设置页脚
*/
public void createFooter(){
Footer footer = xssSheet.getFooter();
footer.setRight("第" + HSSFFooter.page() + "页,共" + HSSFFooter.numPages() + "页");
}
/**
*
* 插入行
* @param startRow
* @param rows
*/
public void insertRows(int startRow, int rows){
int bottomRow = xssSheet.getLastRowNum();
if(startRow > bottomRow){
int n = startRow - bottomRow;
for(int i = 1; i <= n; i++){
xssSheet.createRow(bottomRow + i);
}
}
xssSheet.shiftRows(startRow, xssSheet.getLastRowNum(), rows, true, false);
}
/**
*
* 替换模板中变量
* @param map
*/
public void replaceExcelData(Map<String, String> map){
int rowNum = xssSheet.getLastRowNum();
for(int i = 0;i <= rowNum; i++){
XSSFRow row = xssSheet.getRow(i);
if(row == null) continue;
for(int j = 0;j < row.getPhysicalNumberOfCells();j++){
XSSFCell cell = row.getCell(j);
if(cell == null) continue;
String key = cell.getStringCellValue();
if(map.containsKey(key)){
cell.setCellValue(map.get(key));
}
}
}
}
/**
* 下载excel
* @param response
* @param filaName
* @throws IOException
*/
public void downloadExcel(HttpServletResponse response, String filaName) throws IOException{
String encodeFileName = URLEncoder.encode(filaName,"UTF-8");
response.addHeader("Content-Disposition","attachment;filename=" +encodeFileName);
ServletOutputStream out = response.getOutputStream();
xssWb.write(out);
out.flush();
out.close();
}
}
3.HssExcelExp为03格式(.xls)的实现类
package com.example;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFFooter;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Footer;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
*
* excel导出类
* <p>处理.xls格式<p>
* @since jdk1.6
* @date 2016-6-2
*
*/
public class HssExcelExp extends ExcelExp{
public HssExcelExp() {
super();
}
/**
* 构造函数
* ExcelExp
* @param filePath 文件路径,如com/test/template/test.xls
* @param sheetNum 要操作的页签,0为第一个页签
* @throws IOException
*/
public HssExcelExp(String filePath, int sheetNum) throws IOException {
URL resource = this.getClass().getClassLoader().getResource(filePath);
InputStream is = new FileInputStream(resource.getFile());
hssWb = new HSSFWorkbook(is);
hssSheet = hssWb.getSheetAt(sheetNum);
}
@Override
public void createFooter() {
Footer footer = hssSheet.getFooter();
footer.setRight("第" + HSSFFooter.page() + "页,共" + HSSFFooter.numPages() + "页");
}
@Override
public void downloadExcel(HttpServletResponse response, String filaName) throws IOException {
String encodeFileName = URLEncoder.encode(filaName,"UTF-8");
response.addHeader("Content-Disposition","attachment;filename=" +encodeFileName);
ServletOutputStream out = response.getOutputStream();
hssWb.write(out);
out.flush();
out.close();
}
@Override
public void insertRows(int startRow, int rows) {
int bottomRow = hssSheet.getLastRowNum();
if(startRow > bottomRow){
int n = startRow - bottomRow;
for(int i = 1; i <= n; i++){
hssSheet.createRow(bottomRow + i);
}
}
hssSheet.shiftRows(startRow, hssSheet.getLastRowNum(), rows, true, false);
}
@Override
public void replaceExcelData(Map<String, String> map) {
int rowNum = hssSheet.getLastRowNum();
for(int i = 0;i <= rowNum; i++){
HSSFRow row = hssSheet.getRow(i);
if(row == null) continue;
for(int j = 0;j < row.getPhysicalNumberOfCells();j++){
HSSFCell cell = row.getCell(j);
if(cell == null) continue;
String key = cell.getStringCellValue();
if(map.containsKey(key)){
cell.setCellValue(map.get(key));
}
}
}
}
}
- 使用方法
基于不同的excel格式去实例化不同的实现类即可,调用指定的API可实现相应的功能,例如 添加页脚、插入行、为excel中的变量赋值等。以下面excel格式为例,里面存在变量xlsx_a、xlsx_b、
xlsx_c,要为变量赋值。在第三行要插入行,然后写入数据。
public static void main(String[] args) throws Exception {
//传递模板地址和要操作的页签
ExcelExp excel = new XssExcelExp("com/example/template/test.xlsx", 0);
//创建页脚,打印excel时显示页数
excel.createFooter();
//插入行
int startRow = 2;//起始行
int rows = 5;//插入行数
excel.insertRows(startRow, rows);
//在插入的行中写入数据
wirteXssExcel(excel);
//为模板中变量赋值
Map<String, String> map = new HashMap<String, String>();
map.put("xlsx_a", "2016-06-07 12:00:00");
map.put("xlsx_b", "测试");
map.put("xlsx_c", "12345");
excel.replaceExcelData(map);
//导出,此处只封装了浏览器下载方式
//调用downloadExcel,返回输出流给客户端
String fileName = "export1.xlsx";
excel.downloadExcel(response, fileName);
}
public void wirteXssExcel(ExcelExp excel){
XSSFSheet sheet = excel.getXssSheet();
List list = new ArrayList();
for (int i = 0; i < list.size(); i++) {
XSSFRow row = sheet.createRow(i+3);
row.createCell(0).setCellValue(String.valueOf(i + 1));
row.createCell(1).setCellValue("111");
row.createCell(2).setCellValue("222");
row.createCell(3).setCellValue("333");
}
}
public void wirteHssExcel(ExcelExp excel){
HSSFSheet sheet = excel.getHssSheet();
List list = new ArrayList();
for (int i = 0; i < list.size(); i++) {
HSSFRow row = sheet.createRow(i+3);
row.createCell(0).setCellValue(String.valueOf(i + 1));
row.createCell(1).setCellValue("111");
row.createCell(2).setCellValue("222");
row.createCell(3).setCellValue("333");
}
}
勘误
1.在使用中发现,插入行方法,在模板最后插入行时会报错( java.lang.IllegalArgumentException: firstMovedIndex, lastMovedIndex out of order ),现已修复,文中代码已更新。
来源:oschina
链接:https://my.oschina.net/u/1786940/blog/688303