您的位置:首页 > 运维架构 > Apache

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

2017-10-18 14:39 621 查看
因公司项目需要,临时写的小程序。未优化,结构简单。

稍微修改了一下,懒得写简介,具体用法见上一版说明。

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.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]*[Ee]{1}-{0,1}[0-9]+$");

/**
* 分隔符.
* 默认为英文输入状态下的逗号。
* @see ToExcel#setSeparativeSign(String)
*/
private static String separativeSign = ",";

/**
* 标记是否自动转换单元格格式为数字格式(若待填充的文本为数字).
* 默认为true。
* @see ToExcel#setNumFormat(boolean)
*/
private static boolean transform = true;

/**
* 转换单元格格式为数字格式时,数字保留到小数点后的精度.
* 默认为2。
* @see ToExcel#setDecimal(int)
*/
private static int decimal = 2;

/**
* 等号(英文输入状态).
*/
private static final String equal_sign ="=";

/**
* 字符串“0”.
*/
private static final String zero = "0";

/**
* 字符串“空”.
*/
private static final String blank = "空";

/**
* 设置分隔符.
* 若不设置此项,则默认为英文输入状态下的逗号。
* @param sign
*/
public static void setSeparativeSign(String sign) {
if(sign!=null && sign.isEmpty()==false)
separativeSign = sign;
}

/**
* 设置是否自动转换单元格格式为数字格式(若待填充的文本为数字).
* 若不设置此项,则默认自动转换。
*/
public static void setNumFormat(boolean b) {
transform = b;
}

/**
* 设置转换单元格格式为数字格式时,数字保留到小数点后的精度.
* 若不设置此项,则默认为2。
* @param i
*/
public static void setDecimal(int i) {
if(i>-1)
decimal = i;
}

/**
* 写出内容到Excel.
* @param map:key为Excel中每个分页的名称、value为分页的内容;
* @param fileName:最终输出的文件名,包含路径;
* @throws MyRuntimeException
*/
public static<T> void toExcel(Map<String,List<T>> map,String fileName) 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(excel.createDataFormat().getFormat(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);
} catch(StringIndexOutOfBoundsException e){
throw new MyRuntimeException("分隔符不正确导致无法按“=”分割出表头",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) throws StringIndexOutOfBoundsException{
//若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(separativeSign);
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(separativeSign);//将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 (transform && (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);
}
}
}

}注意事项:MyRuntimeException类请自定义;
例子:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  excel poi 源码分享
相关文章推荐