java根据xml配置文件导出excel通用方法

  java web项目中时常会用到导出功能,而导出excel几乎是每个项目必备的功能之一。针对形形色色的导出方法及个人平时的工作经验,特将导出excel方法整理成通用的方法,根据xml配置来实现特定的导出。

  此方法基于struts2框架实现,先看struts.xml配置文件中的配置方法:

1 <action name="exportExcel" class="exportExcelAction">
2     <result name="download" type="stream">
3         <param name="contentType">application/vnd.ms-excel</param>
4         <param name="contentDisposition">attachment;filename="${excelName}"</param>
5         <param name="inputName">excelStream</param>
6     </result>
7 </action>

  1、excelName对应bean中的excelName属性,为导出文件名称;

  2、excelStream对应bean中导出数据流,即导出方法返回的数据流。

  接着是导出配置文件:excel.xml,需要导出的列表按照规则配置在此xml文件中即可:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <excel>
 3     <element title="检测库信息表" class="com.model.CheckRecord">
 4         <property name="xmmc" display_name="项目名称"></property>
 5         <property name="sampleNo" display_name="样品编号"></property>
 6         <property name="detectTime" display_name="检测日期"></property>
 7         <property name="jcbh" display_name="检测板号"></property>
 8         <property name="ypmc" display_name="样品名称"></property>
 9         <property name="yplx" display_name="样品类型"></property>
10         <property name="ypcd" display_name="样品产地"></property>
11         <property name="resultType" display_name="检测类型"></property>
12         <property name="resultValue" display_name="检测结果"></property>
13         <property name="resultDetect" display_name="检测读数值"></property>
14         <property name="resultTip" display_name="检测提示"></property>
15         <property name="submitStaff" display_name="送检人员"></property>
16         <property name="submitTime" display_name="送检时间"></property>
17     </element>
18 </excel>

  excel节点为根节点,element节点即为需要导出的列表节点,class属性用来唯一区别不同的导出列表,即根据class属性查找需要导出的列表属性集合,title属性当然是导出excel表格的标题咯。

  property节点是需要导出的字段,name属性和javabean中属性一一对应,display_name是excel表格所对应的显示名称。

  不同的导出列表只需要按照上面的实例配置多个element即可,切记class属性要唯一哦。

  接下来就是导出excel工具类啦,先看代码:

  1 package excel.util;
  2 
  3 /**
  4  * 导出excel工具类
  5  * @author BaiFL
  6  */
  7 public class ExportExcelUtil {
  8     
  9     /**标题**/
 10     private String title;
 11     
 12     private InputStream inputStream = null;
 13     
 14     private ByteArrayOutputStream outputStream = null;
 15     
 16     private HSSFWorkbook workbook;
 17     
 18     private HSSFSheet sheet;
 19     
 20     /**表格行**/
 21     private HSSFRow row;
 22     
 23     /**单元格**/
 24     private HSSFCell cell; 
 25     
 26     /**字体**/
 27     private HSSFFont font;
 28     
 29     /**单元格样式**/
 30     private HSSFCellStyle cellStyle;
 31     
 32     /**
 33      * 字段及字段注释
 34      * key:字段名
 35      * value:字段注释
 36      */
 37     private Map<String, String> propertyMap = new HashMap<String, String>();
 38     
 39     /**
 40      * 导出excel
 41      * @param className 完整类名
 42      * @param list 导出结果集
 43      */
 44     public InputStream export(String className, List<?> list){
 45         
 46         //初始化
 47         this.instance(className);
 48         
 49         //设置字体
 50         font = workbook.createFont();
 51         font.setFontName("宋体");
 52         font.setFontHeightInPoints((short) 12);
 53         
 54         //设置单元格类型
 55         cellStyle = workbook.createCellStyle();
 56         cellStyle.setFont(font);
 57         cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
 58         
 59         //创建第一行title
 60         row = sheet.createRow(0);
 61         this.setCellValue(0, title);
 62         //合并单元格:0行~0行,0列~propertyMap.size() - 1列
 63         sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, propertyMap.size() - 1));
 64         
 65         //创建第二行标题行
 66         row = sheet.createRow(1);
 67         int i = 0;
 68         //遍历propertyMap
 69         for(String key : propertyMap.keySet()){
 70             //创建单元格
 71             this.setCellValue(i, propertyMap.get(key));
 72             i++;
 73         }
 74         
 75         //遍历数据集合
 76         for(int j = 0; j < list.size(); j++) {
 77             Object object = list.get(j);
 78             //创建数据行,从第三行开始
 79             row = sheet.createRow(j + 2);
 80             int k = 0;
 81             for(String key : propertyMap.keySet()){
 82                 Field f;
 83                 String value;
 84                 try {
 85                     f = object.getClass().getDeclaredField(key);
 86                     //设置私有字段的可访问性
 87                     f.setAccessible(true);
 88                     //获取字段get方法
 89                     value = String.valueOf(f.get(object));
 90                     //设置单元格
 91                     this.setCellValue(k, value);
 92                     k++;
 93                 } catch (Exception e) {
 94                     // TODO: handle exception
 95                     e.printStackTrace();
 96                 }
 97             }
 98         }
 99         try {
100             outputStream = new ByteArrayOutputStream();
101             workbook.write(outputStream);
102             byte[] content = outputStream.toByteArray();
103             inputStream = new ByteArrayInputStream(content);
104         } catch (IOException e) {
105             // TODO Auto-generated catch block
106             e.printStackTrace();
107         }finally {
108             try {
109                 if(outputStream != null){
110                     outputStream.close();
111                 }
112             } catch (Exception e) {
113                 e.printStackTrace();
114             }
115         }
116         return inputStream;
117     }
118     
119     /**
120      * 初始化
121      * @param className 完整类名
122      * 根据className获取excel.xml文件对应element属性集合
123      */
124     @SuppressWarnings("unchecked")
125     private void instance(String className){
126         //加载配置文件
127         inputStream = ExportExcelUtil.class.
getResourceAsStream("/resources/exportExcel/excel.xml"); 128 129 this.workbook = new HSSFWorkbook(); 130 this.sheet = workbook.createSheet(); 131 132 SAXReader reader = new SAXReader(); 133 134 Document document = null; 135 try { 136 document = reader.read(inputStream); 137 } catch (DocumentException e) { 138 // TODO Auto-generated catch block 139 e.printStackTrace(); 140 } 141 142 //获取根节点 143 Element excel = document.getRootElement(); 144 145 //获取element集合 146 List<Element> elementList = excel.elements("element"); 147 //根据class属性获取对应导出字段属性集合 148 for(Element element : elementList){ 149 if(className.equals(element.attributeValue("class"))){ 150 title = element.attributeValue("title"); 151 //element下所有property集合 152 List<Element> childList = element.elements(); 153 for(Element child : childList){ 154 propertyMap.put(child.attributeValue("name"),
child.attributeValue("display_name")); 155 } 156 } 157 } 158 } 159 160 /** 161 * 设置单元格 162 * @param index 163 * @param value 164 */ 165 private void setCellValue(int index, String value){ 166 //创建单元格,设置单元格属性为文本类型 167 cell = row.createCell(index, HSSFCell.CELL_TYPE_STRING); 168 cell.setCellStyle(cellStyle); 169 cell.setCellValue(value); 170 //设置第index列宽为自动 171 sheet.autoSizeColumn(index); 172 } 173 174 }
   方法export(String className, List<?> list)即导出excel通用方法,参数1:className对应导出配置文件excel.xml文件中element节点的class属 性,为完整类名;参数2:list即需要导出的数据,该list为对象集合,非数组集合。

  下面就是action中如何用啦,前面所有工作做好以后action中只需要很少的代码调用就可以啦,先看代码:
 1     /**
 2      * exportExcel
 3      * @return
 4      */
 5     public String exportExcel() {
 6         //获取数据条数
 7         int count = recordService.count(checkRecord);
 8         //分页
 9         Page page = listForm.getPageObj(count);
10         if(StringUtils.blank(page.getOrderBy())){
11             //默认按检测时间倒序排序
12             page.setOrderBy("detectTime");
13             page.setOrder("desc");
14         }
15         //导出excel
16         if(Constant.EXPORT.equals(export)){
17             page.setPage(0);
18             page.setPageSize(exportSize !=0 && exportSize < count ? exportSize : (count < 65535 ? count : 65535));
19             List<CheckRecord> list = recordService.find(checkRecord, page);
20             excelStream = excel.export(CheckRecord.class.getName(), list);
21             return "download";  
22         }else{
23             List<CheckRecord> list = recordService.find(checkRecord, page);
24             httpServletRequest.setAttribute("List", list);
25             httpServletRequest.setAttribute("Page", page);
26             return "list";
27         }
28     }

  这是普通的页面列表数据展示代码,当属性export值为Constant.EXPORT("export")时,执行导出excel操作,导出数据范围为exportSize~65535;

  action中还必须有excelStream、excelName两个属性,分别和struts中的属性一一对应。

  /**导出excel数据流对应struts中的stream**/
  protected InputStream excelStream;

  /**excel文件名**/
  protected String excelName;

  getter/setter方法这里就不写了,action中可一定要写哦。

  至此,整个导出功能全部实现,赶紧试试吧

  下面的代码无需配置struts,直接导出并下载:

 

  1 package com.jeecms.common.util;
  2 
  3 import java.io.IOException;
  4 import java.io.InputStream;
  5 import java.io.OutputStream;
  6 import java.io.UnsupportedEncodingException;
  7 import java.lang.reflect.Field;
  8 import java.util.Date;
  9 import java.util.LinkedHashMap;
 10 import java.util.List;
 11 import java.util.Map;
 12 
 13 import javax.servlet.http.HttpServletResponse;
 14 
 15 import org.apache.poi.hssf.usermodel.HSSFCell;
 16 import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 17 import org.apache.poi.hssf.usermodel.HSSFFont;
 18 import org.apache.poi.hssf.usermodel.HSSFRow;
 19 import org.apache.poi.hssf.usermodel.HSSFSheet;
 20 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 21 import org.apache.poi.ss.util.CellRangeAddress;
 22 import org.dom4j.Document;
 23 import org.dom4j.DocumentException;
 24 import org.dom4j.Element;
 25 import org.dom4j.io.SAXReader;
 26 
 27 /**
 28  * 导出excel工具类
 29  * @author BaiFL
 30  */
 31 public class ExportExcelUtil {
 32     
 33     /**标题**/
 34     private String title;
 35     
 36     private InputStream inputStream = null;
 37     
 38     private OutputStream os = null;
 39     
 40     private HSSFWorkbook workbook;
 41     
 42     private HSSFSheet sheet;
 43     
 44     /**表格行**/
 45     private HSSFRow row;
 46     
 47     /**单元格**/
 48     private HSSFCell cell; 
 49     
 50     /**字体**/
 51     private HSSFFont font;
 52     
 53     /**单元格样式**/
 54     private HSSFCellStyle cellStyle;
 55     
 56     /**
 57      * 字段及字段注释
 58      * key:字段名
 59      * value:字段注释
 60      */
 61     private Map<String, String> propertyMap = new LinkedHashMap<String, String>();
 62     
 63     /**
 64      * 导出excel
 65      * @param className 完整类名
 66      * @param list 导出结果集
 67      * @param response 
 68      */
 69     public void export(String className, List<?> list, HttpServletResponse response){
 70         
 71         //初始化
 72         this.instance(className);
 73         
 74         response.reset();
 75         
 76         response.setCharacterEncoding("UTF-8");
 77         response.setContentType("application/vnd.ms-excel");
 78         String fileName = null;
 79         try {
 80             fileName = new String(title.getBytes("GBK"), "ISO-8859-1");
 81         } catch (UnsupportedEncodingException e1) {
 82             e1.printStackTrace();
 83         }
 84         response.setHeader("Content-Disposition", "filename=" + fileName + DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")+ ".xls");
 85         
 86         //设置字体
 87         font = workbook.createFont();
 88         font.setFontName("宋体");
 89         font.setFontHeightInPoints((short) 12);
 90         
 91         //设置单元格类型
 92         cellStyle = workbook.createCellStyle();
 93         cellStyle.setFont(font);
 94         cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
 95         
 96         //创建第一行title
 97         row = sheet.createRow(0);
 98         this.setCellValue(0, title);
 99         //合并单元格:0行~0行,0列~propertyMap.size() - 1列
100         sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, propertyMap.size() - 1));
101         
102         //创建第二行标题行
103         row = sheet.createRow(1);
104         int i = 0;
105         //遍历propertyMap
106         for(String key : propertyMap.keySet()){
107             //创建单元格
108             this.setCellValue(i, propertyMap.get(key));
109             i++;
110         }
111         //遍历数据集合
112         for(int j = 0; j < list.size(); j++) {
113             Object object = list.get(j);
114             //创建数据行,从第三行开始
115             row = sheet.createRow(j + 2);
116             int k = 0;
117             for(String key : propertyMap.keySet()){
118                 if(key.indexOf(".") > 0){          //关联对象中的私有属性
119                     String[] keyArr = key.split("\\.");
120                     Field field;
121                     Object obj = object;
122                     for(int t = 0; t < keyArr.length; t++){
123                         if(t + 1 == keyArr.length){  //获取私有字段值
124                             try {
125                                 field = obj.getClass().getDeclaredField(keyArr[t]);
126                                 //设置私有字段的可访问性
127                                 field.setAccessible(true);
128                                 //获取字段get方法
129                                 Object value = field.get(obj);
130                                 //设置单元格
131                                 this.setCellValue(k, (value == null ? "" : String.valueOf(value)));
132                                 k++;
133                             } catch (Exception e) {
134                                 // TODO: handle exception
135                                 e.printStackTrace();
136                             }
137                         }else{  //获取关联对象
138                             try {
139                                 field = obj.getClass().getDeclaredField(keyArr[t]);
140                                 //设置私有字段的可访问性
141                                 field.setAccessible(true);
142                                 //获取字段get方法
143                                 obj = field.get(obj);
144                             } catch (Exception e) {
145                                 // TODO Auto-generated catch block
146                                 e.printStackTrace();
147                             } 
148                         }
149                     }
150                 }else{     //不包含关联对象的私有属性
151                     try {
152                         Field f = object.getClass().getDeclaredField(key);
153                         //设置私有字段的可访问性
154                         f.setAccessible(true);
155                         //获取字段get方法
156                         Object value = f.get(object);
157                         //设置单元格
158                         this.setCellValue(k, (value == null ? "" : String.valueOf(value)));
159                         k++;
160                     } catch (Exception e) {
161                         // TODO: handle exception
162                         e.printStackTrace();
163                     }
164                 }
165             }
166         }
167         try {
168             os = response.getOutputStream();
169             workbook.write(os);
170         } catch (IOException e) {
171             // TODO Auto-generated catch block
172             e.printStackTrace();
173         }finally {
174             try {
175                 if(os != null){
176                     os.close();
177                 }
178             } catch (Exception e) {
179                 e.printStackTrace();
180             }
181         }
182     }
183     
184     
185     /**
186      * 初始化
187      * @param className 完整类名
188      * 根据className获取excel.xml文件对应element属性集合
189      */
190     @SuppressWarnings("unchecked")
191     private void instance(String className){
192         //加载配置文件
193         inputStream = ExportExcelUtil.class.getResourceAsStream("/resources/exportExcel/excel.xml");
194         
195         SAXReader reader = new SAXReader();
196         
197         Document document = null;
198         try {
199             document = reader.read(inputStream);
200         } catch (DocumentException e) {
201             // TODO Auto-generated catch block
202             e.printStackTrace();
203         }
204         
205         //获取根节点
206         Element excel = document.getRootElement();
207 
208         //获取element集合
209         List<Element> elementList = excel.elements("element");
210         //根据class属性获取对应导出字段属性集合
211         for(Element element : elementList){
212             if(className.equals(element.attributeValue("class"))){
213                 title = element.attributeValue("title");
214                 //element下所有property集合
215                 List<Element> childList = element.elements();
216                 for(Element child : childList){
217                     propertyMap.put(child.attributeValue("name"), child.attributeValue("display_name"));
218                 }
219             }
220         }
221         
222         this.workbook = new HSSFWorkbook();
223         this.sheet = workbook.createSheet(title);
224     }
225     
226     /**
227      * 设置单元格
228      * @param index
229      * @param value
230      */
231     private void setCellValue(int index, String value){
232         //创建单元格,设置单元格属性为文本类型
233         cell = row.createCell(index, HSSFCell.CELL_TYPE_STRING);
234         cell.setCellStyle(cellStyle);
235         cell.setCellValue(value);
236         //设置第index列宽为自动
237         sheet.autoSizeColumn(index);
238     }
239 
240 }

 

action中使用方法:

 1     /**
 2      * 导出
 3      * @param queryValue
 4      * @param pageNo
 5      * @param request
 6      * @param response
 7      * @param model
 8      */
 9     @RequestMapping(value = "/addresslist/export.do")
10     public void export(String queryValue, Integer pageNo,
11             HttpServletRequest request, HttpServletResponse response, ModelMap model) {
12         List<CmsUser> list = manager.getExcelList(CmsUtils.getSiteId(request), queryValue);
13         ExportExcelUtil excel = new ExportExcelUtil();
14         excel.export(CmsUser.class.getName(), list, response);
15         log.info("通讯录导出成功!");
16     }

 

 

 


转载于:https://www.cnblogs.com/baifeilong/p/3663375.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值