JAVA源码分享:基于Apache POI,将List<T>内封装的实体类信息写出到磁盘Excel文件(20170925)

来源:互联网 发布:中国人才流失 知乎 编辑:程序博客网 时间:2024/06/03 11:05

因公司项目需要,临时写的小程序。未优化,结构简单。


与上一版(http://blog.csdn.net/qw3670/article/details/56012155)相比的改进:

修改方法为静态方法,使用时无需初始化ToExcel类;

待写出的数据为数字时,会自动转换单元格格式为数字;

输出格式为Excel 2007格式(.xlsx);


共有两个静态方法可供调用:

可使用int decimal参数设置需要保留到数字点后几位;

也可使用无此参数的另一个静态方法,默认保留到小数点后两位;


注意事项:

MyRuntimeException类请自定义;

依赖关系已写在注释中,实测poi-3.16版可用,其他版本未测试;


具体用法见上一版说明。

package tools;import java.io.FileOutputStream;import java.io.IOException;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Map.Entry;import java.util.regex.Pattern;import org.apache.poi.hssf.usermodel.HSSFDataFormat;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.CellStyle;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import entity.MyRuntimeException;/** * 写出到Excel文件.</br> * 依赖:poi-3.16.jar、poi-ooxml-3.16.jar、poi-ooxml-schemas-3.16.jar、 * xmlbeans-2.6.0.jar、commons-collections4-4.1.jar * @author AL *  */public class ToExcel {/** * 匹配数字(非科学计数法). */private static final Pattern general_num=Pattern.compile("^-{0,1}[0-9]+\\.{0,1}[0-9]*$");/** * 匹配数字(科学计数法). */private static final Pattern notation_num=Pattern.compile("^-{0,1}[0-9]+\\.{0,1}[0-9]*E{1}-{0,1}[0-9]+$");/** * 逗号(英文输入状态). */private static final String comma =",";/** * 等号(英文输入状态). */private static final String equal_sign ="=";/** * 字符串“0”. */private static final String zero = "0";/** * 字符串“空”. */private static final String blank = "空";/** * 写出内容到Excel. * 数字类型的信息默认保留到小数点后两位。 * @param map:key为Excel中每个分页的名称、value为分页的内容; * @param fileName:最终输出的文件名,包含路径; * @throws MyRuntimeException */public static<T> void toExcel(Map<String,List<T>> map,String fileName) throws MyRuntimeException {toExcel(map,fileName,2);}/** * 写出内容到Excel. * @param map:key为Excel中每个分页的名称、value为分页的内容; * @param fileName:最终输出的文件名,包含路径; * @param decimal:保留数字类型的信息到小数点后的位数。 * @throws MyRuntimeException */public static<T> void toExcel(Map<String,List<T>> map,String fileName,int decimal) throws MyRuntimeException {//新建文件输出流及Excel表格缓存区FileOutputStream out=null;Workbook excel = null;try {out=new FileOutputStream(fileName+".xlsx");excel = new XSSFWorkbook();StringBuilder sb = new StringBuilder(zero);for(int i=0;i<decimal;i++) {if(i==0) {sb.append(".0");} else {sb.append(zero);}}//此对象用于设置单元格格式为数字格式并保留小数点后两位,备用CellStyle cellStyle = excel.createCellStyle();cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat(sb.toString()));//若map为空,则重构一个map,装入一个空白键值对if(map==null || map.isEmpty()){map=new HashMap<>();map.put(blank, null);}//遍历键值对,将表格名称和表格内容传递给下一层,用于写出for(Entry<String, List<T>> entry : map.entrySet()){//向Excel(缓存区)内填充内容writeWorkbook(entry.getValue(),entry.getKey(),excel,cellStyle);}//写出到磁盘文件excel.write(out);} catch (IOException e) {throw new MyRuntimeException("输出Excel失败",e);} finally {close(excel,out);}}/** * 向Excel(缓存区)内填充内容. * @param result * @param sheetName * @param excel * @param cellStyle  */private static<T> void writeWorkbook(List<T> result, String sheetName, Workbook excel, CellStyle cellStyle) {//若sheetName为空,则填充“空”if(sheetName==null  || sheetName.isEmpty()){sheetName=blank;}Sheet sheet = excel.createSheet(sheetName);// 若集合为空,则写出“空”字符if (result == null || result.isEmpty()) {sheet.createRow(0).createCell(0).setCellValue(blank);return;}//按照“,”将集合内元素toString的字符串切割成数组String[] temp = result.get(0).toString().split(comma);Row row = sheet.createRow(0);//获取此sheet表格的第一行int times=temp.length;for (int t = 0; t < times; t++) {//遍历数组,用于构造表头row.createCell(t).setCellValue(temp[t].substring(0, temp[t].indexOf(equal_sign)));//只取“=”之前的字符}//遍历集合,填充表格内容int size=result.size();for (int i = 1; i <= size; i++) {row = sheet.createRow(i);String[] infos=result.get(i - 1).toString().split(comma);//将toString返回的字符串按","切割成数组int round=infos.length;for (int j = 0; j < round; j++) {//只取“=”之后的字符String info =infos[j].substring(infos[j].indexOf(equal_sign) + 1, infos[j].length()).trim();//获取单元格Cell cell=row.createCell(j);//判断待输入的内容是否是数字if (general_num.matcher(info).matches() || notation_num.matcher(info).matches()) {cell.setCellStyle(cellStyle);cell.setCellValue(Double.parseDouble(info));}else{cell.setCellValue(info);}}}}/** * 关闭资源. * @param acs */private static void close(AutoCloseable... acs) throws MyRuntimeException{if(acs!=null)for (AutoCloseable ac : acs) {if(ac!=null)try {ac.close();} catch (Exception e) {throw new MyRuntimeException("关闭资源失败",e);}}}}


阅读全文
0 0
原创粉丝点击