java實現檔案匯出到Excel
匯出excel功能:
//首先把要匯出檔案的模板放到專案預設的地址下,(也就是webapp地址下)
Controller
@RequestMapping("value="")
//匯出方法
public String getExportExcel(HttpServletRequest request, HttpSeiions session,
HttpServletResponse response,//包括前臺傳過來的引數(自己定義) ){
log.info("--------------正在匯出檔案");
//獲取模板的位置,以及要匯出的路徑
//模板的位置
String modelPath = session.getServletContext().getRealPath("/")+"模板的位置.xlsx";
//匯出的路徑地址
String hisPath = session.getServletContext().getRealPath("/")+"匯出的路徑";
//相當於模板物件
Workbook book;
try{
//獲取模板檔案
File excelFile = new File(modelPath);
book = WorkbookFactory.creat(excelFile);
//獲取你要匯出的資訊,將其封裝為list物件(就是業務邏輯處理的結果集)
//List<封裝的實體類> list = 你的service層.service方法(前臺傳的引數);
如:List<AmReportFormSalePriceSection> amReportingList = amReportingService.getSalePriceSectionList(propertyLevel, priceSection, wslName);
//你的service層.匯出的方法(book, list, hisPath);
如:amReportingService.getReportFormSalePriceSectionExcel(book, amReportingList, hisPath);
//如果你要匯出的excel是多個sheet組成的,並且在匯出後只顯示當前的某一個sheet,
//其他sheet都預設刪除,則執行下面的遍歷刪除,如果不需要則不用執行
/**
* for(sheet的數量遍歷){
* if(當不是當前顯示的sheet則進行刪除){
* book.removeSheetAt(遍歷序號);
* }
*/
//設定匯出格式
response.setCharacterEncoding("utg-8");
//設定檔案ContentType型別,這樣設定會自動判斷下載檔案型別
response.setContentType("multipart/form-data");
//設定檔案頭;最後一個引數是設定下載檔名
response.setHeader("Content-Disposition", "attachment;fileName="+new String("匯出檔案的名稱".getBytes("UTF-8"),"ISO-8859-1")+".xlsx");
response.setHeader("Pragma","No-cache");
OutputStream out = response.getOutputStream();
book.write(out);
out.flush();
out.close();
}catch(Exception e){
log.error("發生異常 msg={}","原因:",e);
return 匯出失敗資訊;
}
return 匯出成功資訊;
}
Service實現類:
@Override
public void getExportExcel(Workbook book, List<AmReportFormSalePriceSection> amReportingList,
String hisPath){
try{
//獲取要匯出的excel模板中的該sheet(也就是當前要匯出的sheet的下標(一般都以零為第一個))
Sheet sheetArea = book.getSheetAt(6); //假設現在要匯出的sheet是在模板中的第七個
int rowNum = 10; //在要匯出的sheet中,匯出資料是從該sheet中的第幾行開始資料匯出的(起始下標也是從零開始)
Row dkCopyRow = sheetArea.getRow(10);
//開始遍歷匯出的資料,進行資料匯出
while(amReportingList != null && amReportingList.size() > 0){
//由於匯出資料過多,則進行分頁匯出,每頁2000條內,所以要設定一個臨時集合存放當前匯出的資料(每一頁)
List<AmReportFormSalePriceSection> subList = amReportingList.subList(0,Math.min(2000,amReportingList.size()));
for(AmReportFormSalePriceSection reportForm : subList){
Row trow = sheetArea.getRow(rowNum);
if(trow == null){
trow = sheetArea.createRow(rowNum);
ExcelUtil.copyRow(book, dkCopyRow, trow);
}
//service實現類中的方法(實現單挑要匯出的資料填入excel中的一行)
seRowValueOfSheet(reportForm, trow, 10);
rowNum++;
}
//進行釋放該集合
subList.clear(Exception e);
}
}catch(Exception e){
log.error("發生異常 msg={}", "原因:", e);
throw new RuntimeException(e);
}
}
//service實現類中的方法(實現單條要匯出的資料填入excel中的一行)
public void seRowValueOfSheet(Object o, Row row, int sheetNum){
//getDeclareFields()方法返回該類中所有的欄位包括共有的和私有的
//getFieds()方法是返回該類對應的公共類欄位
List<Field> list = Arrays.asList(o.getClass().getDeclareFields());
for(int i = 0; i < list.size(); i++){
Field field = list.get(i);
if(field.isAnnotationPresent(ImportSign.class)){
//ImportSign是單獨建立的一個有關匯出註解的類具體在下面(@註釋)
ImportSign importSign = field.getAnnotation(ImportSign.class);
int cellNum = importSign.cellNum();
if(cellNum == -1){
continue;
}
Cell cell = row.getCell(cellNum);
if(cell == null){
cell = row.createCell(cellNum);
CellStyle cellStyle = cell.getCellStyle();
cellStyle.setClocked(false);
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
}
//獲取該欄位的資料型別
String fieldTypeName = field.getType().getName();
try{
//獲取該欄位的編碼
String fileName = field.getName();
//通過該欄位來獲取該欄位的get方法
Method method = o.getClass().getMethod(
"get" + fileName.subString(0,1).toUpperCase() + fileName.subString(1));
//執行該欄位的get方法,獲取該欄位的值
Object v = method.invoke(o);
if (null != v) {
if (fieldTypeName.) {
cell.setCellValue(v.toString());
}else if (fieldTypeName.contains("BigDecimal")) {
BigDecimal b = new BigDecimal(v.toString());
cell.setCellValue(b.doubleValue());
} else if (fieldTypeName.contains("Date")) {
SimpleDateFormat sd = new SimpleDateFormat("yyyy/MM/dd");
cell.setCellValue(sd.format(new Date(v.toString())));
}
}
}catch(Exception e){
log.error("發生異常 msg={}", "原因:", e);
}
}
}
}
ExcelUtil類
public class ExcelUtil [
/**
*行復制功能
*/
public static void copyRow(Workbook wb, Row fromRow, Row toRow) {
toRow.setHeight(fromRow.getHeight());
CellStyle newStyle = wb.createCellStyle();
for(Iterator<Cell> cellTt = fromRow.cellIterator(); cellTt.hasNext();) {
Cell tmpCell = (Cell) cellTr.next();
Cell newCell = toRow.createCell(tmpCell.getColumnIndex());
copyCell(wb, newStyle, tmpCell, newCell);
}
Sheet worksheet = fromRow.getSheet();
for(int i = 0; i < worksheet.getNumMergedRegions(); i++) {
CellRangeAddress cellRangeAndress = worksheet.getMergedRegion(i);
if(cellRangeAddress.getFirstRow() == fromRow.getRowNum()) {
CellRangeAddress newCellRangeAddress = new CellRangeAddress(toRow.getRowNum(), (toRow.getRowNum() +
(cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow())), cellRangeAddress
.getFirstColumn(), cellRangeAddress.getLastColumn());
worksheet.addMergedRegionUnsafe(newCellRangeAddress);
}
}
}
/**
*複製單元格
* @param srcCell
* @param distCell
* @param //copyValueFlag true則連同cell的內容一起復制
*/
public static void copyCell(Workbook wb,CellStyle newStyle, Cell srcCell, Cell distCell) {
CellStyle srcStyle = srcCell.getCellStyle();
newStyle.cloneStyleFrom(srcStyle);
newStyle.setFont(wb.getFontAt(srcStyle.getFontIndex()));
newStyle.setLocked(false);
newStyle.setBorderTop(BorderStyle.THIN);
newStyle.setBorderBottom(BorderStyle.THIN);
newStyle.setBorderLeft(BorderStyle.THIN);
newStyle.setBorderRight(BorderStyle.THIN);
//樣式
distCell.setCellStyle(newStyle);
//評論
if(srcCell.getCellComment() != null) {
distCell.setCellComment(srcCell.getCellComment());
}
// 不同資料型別處理
CellType srcCellType = srcCell.getCellTypeEnum();
distCell.setCellType(srcCellType);
if(srcCellType == CellType.NUMERIC) {
if(org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(srcCell)) {
distCell.setCellValue(srcCell.getDateCellValue());
} else {
distCell.setCellValue(srcCell.getNumericCellValue());
}
} else if(srcCellType == CellType.STRING) {
distCell.setCellValue(srcCell.getRichStringCellValue());
} else if(srcCellType == CellType.BLANK) {
} else if(srcCellType == CellType.BOOLEAN) {
distCell.setCellValue(srcCell.getBooleanCellValue());
} else if(srcCellType == CellType.ERROR) {
distCell.setCellErrorValue(srcCell.getErrorCellValue());
} else if(srcCellType == CellType.FORMULA) {
distCell.setCellFormula(srcCell.getCellFormula());
} else {
}
}
}
@註釋:
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ImportSign {
int cellNum() default -1;//excel 列序號
boolean isnull() default false;//是否可以為空,預設不可以為空
boolean isYn() default false;//單元格是否為是/否值,如果等於true時自動將是轉換成1,否轉換成0
boolean isDict() default false;//單元格是否為資料字典值,如果等於true時,則需要轉換
int columnLength() default 0; //單元格值位元組長度
String dictGroupCode() default "";//當isDict為true時,設定對應的字典組編碼
String description() default "";//描述
}
在實現匯出功能的時候,我們使用欄位加註解的方式)
在實體類中需要進行匯出的欄位上加註解
如:
@ImportSign(cellNum = 1, isnull = true, description = "區域名稱", columnLength = 50)
private String areaName;