好久没有更新博客了,最近系统需要导出在导出各种各样的Excel,所以就记录一下poi导出Excel的文档吧!
POI 概念
- Workbook:excel的文档对象,一个文档可以包含多个Sheet表格
- Sheet:excel的Sheet表格对象
- Row:excel的行对象
- Cell:excel的格子单元对象
- Font:excel字体对象
- CellStyle:cell样式对象
封装POI,根据模板导出文件
1.这里随意举个例子:
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 封装Excel导出方法,使用公共模板导出
*/
public class ExcelUtils {
private Workbook workbook; // Excel对象,在此使用workbook来适配XSSFWorkbook和HSSFWorkbook两种模式
/**
* 空的构造方法
*/
public ExcelUtils() {
this.workbook = new XSSFWorkbook();
}
/**
* 构造Excel2007及其以后的版本
* @param xssfWorkbook
*/
public ExcelUtils(XSSFWorkbook xssfWorkbook) {
this.workbook = xssfWorkbook;
}
/**
* 构造Excel2007以前的版本
* @param hssfWorkbook
*/
public ExcelUtils(HSSFWorkbook hssfWorkbook) {
this.workbook = hssfWorkbook;
}
/**
* 根据模板渲染生成Excel时,读取模板Excel
* 系统会根据后缀名称匹配Excel的版本信息,如果后缀不对,或者文件不存在,在返回null
* @param excelPath
* @return
*/
public static ExcelUtils getExcelUtil(String excelPath) {
File f = new File(excelPath);
if(!f.exists())
return null;
try(FileInputStream fis = new FileInputStream(f)) {
if(".xls".equals(excelPath.substring(excelPath.lastIndexOf(".")))) {
return new ExcelUtils(new HSSFWorkbook(fis));
} else if(".xlsx".equals(excelPath.substring(excelPath.lastIndexOf(".")))) {
return new ExcelUtils(new XSSFWorkbook(fis));
} else {
throw null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 清空指定下表的sheet中的全部内容
*/
public void clear() {
Sheet sheet = workbook.getSheetAt(0);
for(int i = sheet.getLastRowNum();i >= 0;i--) {
sheet.removeRow(sheet.getRow(i));
}
for (int i = sheet.getNumMergedRegions()-1;i >= 0;i--) {
sheet.removeMergedRegion(i);
}
}
/**
* 生成一个sheet,并将主模板信息拷贝
*/
public void copy() {
Sheet record = workbook.createSheet();
Sheet sheet = workbook.getSheetAt(0);
for (int i = 0;i <= sheet.getLastRowNum();i++) {
Row souRow = sheet.getRow(i);
Row newRow = record.createRow(i);
for (int j = 0;j < souRow.getLastCellNum();j++) {
Cell newCell = newRow.createCell(j);
newCell.setCellValue(souRow.getCell(j).getStringCellValue());
newCell.setCellStyle(souRow.getCell(j).getCellStyle());
}
}
for(int i = 0;i < sheet.getNumMergedRegions();i++) {
CellRangeAddress souRange = sheet.getMergedRegion(i);
CellRangeAddress newRange = new CellRangeAddress(souRange.getFirstRow(), souRange.getLastRow(), souRange.getFirstColumn(), souRange.getLastColumn());
record.addMergedRegion(newRange);
}
}
/**
* 将拷贝模板追加到主模板尾部,重新填充
*/
public void paste() {
Sheet record = workbook.getSheetAt(workbook.getNumberOfSheets() - 1);
Sheet sheet = workbook.getSheetAt(0);
int lastNum = sheet.getLastRowNum() + 1;
for (int i = 0;i <= record.getLastRowNum();i++) {
Row souRow = record.getRow(i);
Row newRow = sheet.createRow(lastNum + i);
for (int j = 0;j < souRow.getLastCellNum();j++) {
Cell cell = newRow.createCell(j);
cell.setCellValue(souRow.getCell(j).getStringCellValue());
cell.setCellStyle(souRow.getCell(j).getCellStyle());
}
}
for(int i = 0;i < record.getNumMergedRegions();i++) {
CellRangeAddress souRange = record.getMergedRegion(i);
CellRangeAddress newRange = new CellRangeAddress(souRange.getFirstRow() + lastNum, souRange.getLastRow() + lastNum, souRange.getFirstColumn(), souRange.getLastColumn());
sheet.addMergedRegion(newRange);
}
}
/**
* 删除拷贝的模板
*/
public void removeModel() {
workbook.removeSheetAt(workbook.getNumberOfSheets() - 1);
}
/**
* 填充头部信息,使用实体类的方式
* 这里不是代表头,而是使用#开头的单元格标识
* @param object
*/
public void replaceHead(Object object) {
for (Row row : workbook.getSheetAt(0)) {
for (Cell cell : row) {
if(cell.getCellType() == 1) {
String cellValue = cell.getStringCellValue().trim();
if(cellValue.startsWith("#")) {
String key = cellValue.substring(1);
Class<?> clazz = object.getClass();
Field f = null;
try {
f = clazz.getDeclaredField(key);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
boolean flag = f.isAccessible();
f.setAccessible(true);
try {
String value = "";
if(f.get(object) != null){
if("timestamp".equalsIgnoreCase(f.getType().getSimpleName())){
value = new SimpleDateFormat("YYYY-MM-dd").format((Timestamp) f.get(object));
}else{
value = String.valueOf(f.get(object));
}
}
cell.setCellValue(value);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
f.setAccessible(flag);
}
}
}
}
}
/**
* 填充头部信息,使用Map的方式
* 这里不是代表头,而是使用#开头的单元格标识
* @param map
*/
public void replaceHead(Map<String, Object> map) {
for (Row row : workbook.getSheetAt(0)) {
for (Cell cell : row) {
if(cell.getCellType() == 1) {
String cellValue = cell.getStringCellValue().trim();
if(cellValue.startsWith("#")) {
String key = cellValue.substring(1);
String value = "";
if(map.get(key) != null) {
if(map.get(key) instanceof Timestamp){
value = new SimpleDateFormat("YYYY-MM-dd").format((Timestamp) map.get(key));
}else{
value = String.valueOf(map.get(key));
}
} else {
value = "";
}
cell.setCellValue(value);
}
}
}
}
}
/**
* 填充单list模板身部
* @param list
*/
public void replaceList(List<?> list) {
Sheet sheet = workbook.getSheetAt(0);
int rowIndex = 0;
Map<String, Cell> map = new HashMap<>();
for (Row row : sheet) {
for (Cell cell : row) {
if(cell.getCellType() == 1) {
String cellValue = cell.getStringCellValue().trim();
if(cellValue.startsWith("list.")) {
rowIndex = row.getRowNum();
String key = cellValue.substring(5);
map.put(key, cell);
}
}
}
}
if(list.size() > 1) {
int lastRowNo = sheet.getLastRowNum();
sheet.shiftRows(rowIndex + 1, lastRowNo, list.size() - 1);
for(int i = rowIndex + 1;i < list.size() + rowIndex;i++) {
Row souRow = sheet.getRow(rowIndex);
Row newRow = sheet.createRow(i);
for (int j = 0;j < souRow.getLastCellNum();j++) {
Cell cell = newRow.createCell(j);
cell.setCellValue(souRow.getCell(j).getStringCellValue());
cell.setCellStyle(souRow.getCell(j).getCellStyle());
}
}
}
setListCell(list, rowIndex, map);
}
/**
* 填充list数据到excel
* @param list
* @param start
* @param map
*/
private void setListCell(List<?> list, int start, Map<String, Cell> map) {
Sheet sheet = workbook.getSheetAt(0);
for (int i = 0; i < list.size(); i++) {
// Row row = sheet.createRow(start++);
Row row = sheet.getRow(start++);
Object o = list.get(i);
for (String s : map.keySet()) {
Cell cell = map.get(s);
Cell c = row.getCell(cell.getColumnIndex());
setCell(c, o, s, cell);
}
}
}
/**
* 设置单元格
* @param c
* @param object
* @param fieldName
* @param cell
*/
private void setCell(Cell c, Object object, String fieldName, Cell cell) {
Class<?> clazz = object.getClass();
Field f = null;
try {
f = clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
boolean flag = f.isAccessible();
f.setAccessible(true);
try {
c.setCellValue(String.valueOf(f.get(object)));
if(String.valueOf(f.get(object))=="null"){
c.setCellValue("");
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
f.setAccessible(flag);
}
/**
* 以流的方式输出Excel
* @param out
*/
public void writeStream(OutputStream out) {
try {
workbook.write(out);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}