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;  
    }  
  
}  

谨以此文章献给有帮助的人,当然了,注释中可以看出来,我有参考别人的文章,但是它的不灵活,我在此基础上进行了改造,确切的说是全部重写了方法,方便使用。有问题欢迎指出!多多探讨才能进步嘛!!

猜你喜欢

转载自blog.csdn.net/u014135369/article/details/83181396