java根據模板匯出excel(二)
阿新 • • 發佈:2018-11-19
最近在做一個專案,關於excel的匯出問題,上網查了很多,最後自己整理並編寫了關於模板匯出的方法,可能會有一些侷限性,但是對於簡單的模板匯出功能是可以實現的,先留下筆記,以供日後參考!思路其實很簡單,主要分為:(1)讀取模板excel(2)迴圈模板excel的每一行,將對應的標籤替換成對應的數值
第一,模板如下:
匯出後如下圖所示:
第二,直接上程式碼吧
1.控制層(controller層)中主要是模板的路徑問題,需要特別注意下!模板的位置如圖:
具體的程式碼如下:
/** * 列表匯出邏輯 * @Title: excelExp * @param voiceLandingBaseinfo * @param request * @param response * @param model 設定檔案 * @return void 返回型別 * @author duyp * @date 2018年8月24日 下午2:55:23 * */ @RequestMapping(value = {"excelExp"}) public void excelExp(MsgCbmSpecialprovisions msgCbmSpecialprovisions,MsgCbmBaseinfo msgCbmBaseinfo, HttpServletRequest request, HttpServletResponse response, Model model) { try { // 查詢滿足條件的業務建檔資訊 String id=request.getParameter("id"); msgCbmSpecialprovisions.setRefid(id); Map<String, String> map = msgCbmSpecialprovisionsService.getExpList(msgCbmSpecialprovisions,msgCbmBaseinfo); response.setContentType("application/OCTET-STREAM"); String filename = CommonUtil.encodeChineseDownloadFileName(request, Constants.EXP_EXCEL_NAME10); response.setHeader("Content-Disposition", "attachment;filename=" + filename); OutputStream out = response.getOutputStream(); String excelModelPath =request.getSession().getServletContext().getRealPath("")+ "/excelmodel/msgCbmSpecialprovisions.xls"; //這個是我的excel模板 ExcelUtilAddByDu.replaceModelNew(excelModelPath, 0, map, out); } catch (IOException e) { e.printStackTrace(); } }
2,服務層(service層)程式碼
/** *匯出資訊組裝 * @Title: getExpList * @param msgCbmSpecialprovisions * @return 設定檔案 * @return Map<String,String> 返回型別 * @author duyp * @date 2018年10月18日 下午2:55:58 * */ public Map<String, String> getExpList(MsgCbmSpecialprovisions msgCbmSpecialprovisions,MsgCbmBaseinfo msgCbmBaseinfo){ //查詢需要匯出的資訊 MsgCbmSpecialprovisions objEntity=findListByRefid(msgCbmSpecialprovisions); Map<String, String> mapc = new HashMap<String, String>(); if(!ObjectUtils.isNullOrEmpty(objEntity)){ mapc.put("date",DateUtils.getDate("yyyy-MM-dd")); mapc.put("sales",msgCbmBaseinfo.getSales()); mapc.put("customservice",msgCbmBaseinfo.getCustomservice()); mapc.put("customername",msgCbmBaseinfo.getCustomername()); mapc.put("customertype",msgCbmBaseinfo.getCustomertype()); mapc.put("demandBrief", StringEscapeUtils.unescapeHtml4(objEntity.getDemandBrief())); // 需求簡述 mapc.put("cbmTerms", StringEscapeUtils.unescapeHtml4(objEntity.getCbmTerms())); // 合同條款 mapc.put("customerDemand", StringEscapeUtils.unescapeHtml4(objEntity.getCustomerDemand())); //客戶要求 mapc.put("financialLegalOpinion", StringEscapeUtils.unescapeHtml4(objEntity.getFinancialLegalOpinion())); // 財經法務意見 mapc.put("legalOpinion", StringEscapeUtils.unescapeHtml4(objEntity.getLegalOpinion())); // 法務意見 mapc.put("upgradeDealInstruction", StringEscapeUtils.unescapeHtml4(objEntity.getUpgradeDealInstruction())); // 升級處理說明 mapc.put("upgradeDealPerson", StringEscapeUtils.unescapeHtml4(DictUtils.getDictLabelPeoples(objEntity.getUpgradeDealPerson(), ""))); // 升級處理人(自動顯示為特批人) } return mapc; }
3,匯出excel處理的工具類如下:
/** * 替換Excel模板檔案內容 (自己寫的方法,可能考慮不周,後面多多補充吧) * @Title: replaceModelNew * @param map 鍵值對儲存要替換的資料 * @param sourceFilePath Excel模板檔案路徑 * @param sheetNum 代表第幾個sheet,下標從0開始 * @param out * @return 設定檔案 * @return boolean 返回型別 * @author duyp * @date 2018年10月18日 下午3:53:58 * */ public static void replaceModelNew(String sourceFilePath,int sheetNum, Map<String, String> map, OutputStream out) { try { POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream(sourceFilePath)); HSSFWorkbook wb = new HSSFWorkbook(fs); HSSFSheet sheet = wb.getSheetAt(sheetNum);//獲取第一個sheet裡的內容 //迴圈map中的鍵值對,替換excel中對應的鍵的值(注意,excel模板中的要替換的值必須跟map中的key值對應,不然替換不成功) if(!ObjectUtils.isNullOrEmpty(map)){ for(String atr:map.keySet()){ int rowNum= sheet.getLastRowNum();//該sheet頁裡最多有幾行內容 for(int i=0;i<rowNum;i++){//迴圈每一行 HSSFRow row=sheet.getRow(i); int colNum=row.getLastCellNum();//該行存在幾列 for(int j=0;j<colNum;j++){//迴圈每一列 HSSFCell cell = row.getCell((short)j); String str = cell.getStringCellValue();//獲取單元格內容 (行列定位) if(atr.equals(str)){ //寫入單元格內容 cell.setCellType(HSSFCell.CELL_TYPE_STRING); cell.setCellValue(map.get(atr)); //替換單元格內容 } } } } } // 輸出檔案 wb.write(out); out.close(); } catch (Exception e) { e.printStackTrace(); } }
到此整個的模板匯出方法就完事了!
下面我會貼出一些別的東西,可以直接進行測試的測試類等東西!
ExcelUtilAddByDu類
package com.thinkgem.jeesite.common.utils.excel.exportByModel;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import com.thinkgem.jeesite.common.utils.ObjectUtils;
public class ExcelUtilAddByDu {
/**
* 替換Excel模板檔案內容
* @param datas 文件資料
* @param sourceFilePath Excel模板檔案路徑
* @param targetFilePath Excel生成檔案路徑
*/
public static boolean replaceModel(List<ExcelReplaceDataVO> datas, String sourceFilePath, String targetFilePath) {
boolean bool = true;
try {
POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream(sourceFilePath));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
for (ExcelReplaceDataVO data : datas) {
//獲取單元格內容
HSSFRow row = sheet.getRow(data.getRow());
HSSFCell cell = row.getCell((short)data.getColumn());
String str = cell.getStringCellValue();
//替換單元格內容
str = str.replace(data.getKey(), data.getValue());
//寫入單元格內容
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cell.setCellValue(str);
}
// 輸出檔案
FileOutputStream fileOut = new FileOutputStream(targetFilePath);
wb.write(fileOut);
fileOut.close();
} catch (Exception e) {
bool = false;
e.printStackTrace();
}
return bool;
}
/**
* 替換Excel模板檔案內容 (主方法測試用)
* @Title: replaceModelTest
* @param sheetNum 代表第幾個sheet,下標從0開始
* @param map 鍵值對儲存要替換的資料
* @param sourceFilePath Excel模板檔案路徑
* @param targetFilePath Excel生成檔案路徑
* @return boolean 返回型別
* @author duyp
* @date 2018年10月18日 下午4:05:21
*
*/
public static boolean replaceModelTest(int sheetNum, Map<String, String> map, String sourceFilePath, String targetFilePath) {
boolean bool = true;
try {
POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream(sourceFilePath));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(sheetNum);//獲取第一個sheet裡的內容
//迴圈map中的鍵值對,替換excel中對應的鍵的值(注意,excel模板中的要替換的值必須跟map中的key值對應,不然替換不成功)
if(!ObjectUtils.isNullOrEmpty(map)){
for(String atr:map.keySet()){
int rowNum= sheet.getLastRowNum();//該sheet頁裡最多有幾行內容
for(int i=0;i<rowNum;i++){//迴圈每一行
HSSFRow row=sheet.getRow(i);
int colNum=row.getLastCellNum();//該行存在幾列
for(int j=0;j<colNum;j++){//迴圈每一列
HSSFCell cell = row.getCell((short)j);
String str = cell.getStringCellValue();//獲取單元格內容 (行列定位)
if(atr.equals(str)){
//寫入單元格內容
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cell.setCellValue(map.get(atr)); //替換單元格內容
}
}
}
}
}
// 輸出檔案
FileOutputStream out = new FileOutputStream(targetFilePath);
wb.write(out);
out.close();
} catch (Exception e) {
bool = false;
e.printStackTrace();
}
return bool;
}
/**
* 替換Excel模板檔案內容 (自己寫的方法,可能考慮不周,後面多多補充吧)
* @Title: replaceModelNew
* @param map 鍵值對儲存要替換的資料
* @param sourceFilePath Excel模板檔案路徑
* @param sheetNum 代表第幾個sheet,下標從0開始
* @param out
* @return 設定檔案
* @return boolean 返回型別
* @author duyp
* @date 2018年10月18日 下午3:53:58
*
*/
public static void replaceModelNew(String sourceFilePath,int sheetNum, Map<String, String> map, OutputStream out) {
try {
POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream(sourceFilePath));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(sheetNum);//獲取第一個sheet裡的內容
//迴圈map中的鍵值對,替換excel中對應的鍵的值(注意,excel模板中的要替換的值必須跟map中的key值對應,不然替換不成功)
if(!ObjectUtils.isNullOrEmpty(map)){
for(String atr:map.keySet()){
int rowNum= sheet.getLastRowNum();//該sheet頁裡最多有幾行內容
for(int i=0;i<rowNum;i++){//迴圈每一行
HSSFRow row=sheet.getRow(i);
int colNum=row.getLastCellNum();//該行存在幾列
for(int j=0;j<colNum;j++){//迴圈每一列
HSSFCell cell = row.getCell((short)j);
String str = cell.getStringCellValue();//獲取單元格內容 (行列定位)
if(atr.equals(str)){
//寫入單元格內容
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cell.setCellValue(map.get(atr)); //替換單元格內容
}
}
}
}
}
// 輸出檔案
wb.write(out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
測試類TestExcelReplace
package com.thinkgem.jeesite.common.utils.excel.exportByModel;
import java.util.HashMap;
import java.util.Map;
public class TestExcelReplace {
public static void main(String[] args) {
//原始的方法如下,我覺得不靈活,後面進行了改造
List<ExcelReplaceDataVO> datas = new ArrayList<ExcelReplaceDataVO>();
// 找到第14行第2列的company,用"XXX有限公司"替換掉company
ExcelReplaceDataVO vo1 = new ExcelReplaceDataVO();
vo1.setRow(1);
vo1.setColumn(1);
vo1.setKey("company");
vo1.setValue("XXX有限公司");
// 找到第5行第2列的content,用"aa替換的內容aa"替換掉content
ExcelReplaceDataVO vo2 = new ExcelReplaceDataVO();
vo2.setRow(1);
vo2.setColumn(3);
vo2.setKey("content");
vo2.setValue("aa替換的內容aa");
datas.add(vo1);
datas.add(vo2);
// d:\\template.xls為Excel模板檔案,d:\\test.xls為程式根據Excel模板檔案生成的新檔案
ExcelUtil.replaceModel(datas, "d:\\test.xls", "d:\\test2.xls");
//改造後的測試方法
Map<String, String> map=new HashMap<String, String>();
map.put("company", "1");
map.put("content", "2");
ExcelUtilAddByDu.replaceModelTest(0,map, "d:\\test.xls", "d:\\test3.xls");
}
}
中間的實體類ExcelReplaceDataVO
package com.thinkgem.jeesite.common.utils.excel.exportByModel;
/**
* Excel替換內容儲存物件
*
* @author Administrator
*
*/
public class ExcelReplaceDataVO {
private int row;// Excel單元格行
private int column;// Excel單元格列
private String key;// 替換的關鍵字
private String value;// 替換的文字
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
謹以此文章獻給有幫助的人,當然了,註釋中可以看出來,我有參考別人的文章,但是它的不靈活,我在此基礎上進行了改造,確切的說是全部重寫了方法,方便使用。有問題歡迎指出!多多探討才能進步嘛!!