1. 程式人生 > >java根據模板匯出excel(二)

java根據模板匯出excel(二)

       最近在做一個專案,關於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;  
    }  
  
}  

謹以此文章獻給有幫助的人,當然了,註釋中可以看出來,我有參考別人的文章,但是它的不靈活,我在此基礎上進行了改造,確切的說是全部重寫了方法,方便使用。有問題歡迎指出!多多探討才能進步嘛!!