好久沒有更新博客了,最近系統需要導出在導出各種各樣的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();
}
}
}
}