package cn.windy.samary.utils.excelUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;import cn.windy.samary.module.shop.Vo.AliVo;
import cn.windy.samary.utils.DateUtil;
import org.apache.log4j.Logger;
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;/**
• @Auther: kxs
• @Date: 2019/8/19 08:51
• @Description:
*/
public class NewExcelUtils {
private static final Logger logger = Logger.getLogger(NewExcelUtils.class);
/**• 利用java反射,将java实体类中的数据写入到excel表格中
• @param excelUrl 要写入数据的excel表格的绝对路径
• @param dateList 要写入excel表格的数据集
• @param classType 封装数据的实体类类型
• @param startRow 从excel表格的第 startRow行开始写入数据。假如是从第三行开始写入数据,那么startRow=2
• @param total 写入实体类中的前 total 个字段的数据,因为一个实体类可能有很多字段,但是只有部分字段是需要使用的,并且,实体类中的字段顺序应保持与excel表中每个指定单元格的位置一致,否则会造成写入的数据混乱或失败
*/
public static void appendDateToExcel(String excelUrl, List<?> dateList, Class<?> classType,
int startRow, int total) throws Exception {
FileInputStream fs = null;
FileOutputStream out = null;
HSSFWorkbook wb = null;
try {Field[] fields = classType.getDeclaredFields();// 得到对象中的字段
fs = new FileInputStream(excelUrl); // 获取head.xls
POIFSFileSystem ps = new POIFSFileSystem(fs); // 使用POI提供的方法得到excel的信息
wb = new HSSFWorkbook(ps);
HSSFSheet sheet = wb.getSheetAt(0); // 获取到工作表,因为一个excel可能有多个工作表
out = new FileOutputStream(excelUrl); // 向head.xls中写数据
// 利用反射获取对象中的所有字段
Field field = null;
String fieldName = null;
String getMethodName = null;
Method getMethod = null;
HSSFRow row = null;
String type = null;
Object obj = null;
Object o = null;
int num=0;
// 遍历所有的对象
for (int i = 0, k = startRow; i < dateList.size(); i++, k++) {
o = dateList.get(i);
// 从指定行开始写入,如果是第3行开始写,则k=2(excel中的行默认从0开始)
row = sheet.createRow((short) (k));
//因为我的excel表中每一行的第一个单元格都是序号,此处可按需要修改
// row.createCell(0).setCellValue(++num);
// 一个实体类中可能有很多字段,但是只有部分字段才是我们需要的,将需要的字段放在实体类中的最前面,并设置读取位置
for (int j = 0; j < total; j++) {
field = fields[j];
fieldName = field.getName();
getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
getMethod = classType.getMethod(getMethodName);
obj = getMethod.invoke(o);// 调用对象的getXXX方法
// 这个字段是空值,就取消写入
if (obj == null) {
continue;
}
// 获取属性类型
type = field.getGenericType().toString();
switch (type) {
case "class java.lang.String":
row.createCell(j).setCellValue(rvZeroAndDot((String) obj));
break;
case "class java.lang.Integer":
row.createCell(j).setCellValue((Integer) obj);
break;
case "class java.lang.Double":
row.createCell(j).setCellValue((Double) obj);
break;
case "class java.lang.Boolean":
row.createCell(j).setCellValue((Boolean) obj);
break;
case "class java.util.Date"://日期类型的数据直接转换成字符串格式写入,否则读到excel表后可能无法识别
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
row.createCell(j).setCellValue(sdf.format((Date) obj));
break;
default:
row.createCell(j).setCellValue((String) obj);
break;
}
}
}} catch (Exception e) {
logger.info(“往excel表中写入数据异常:” + e.getMessage());
throw e;
} finally {
try {
if (out != null) {
out.flush();
}if (wb != null) {
wb.write(out);
}
if (out != null) {
out.close();
}
} catch (Exception e) {
logger.info("往excel表格写入数据异常:"+e.getMessage());
}}
}
//去除数后面多余的0
public static String rvZeroAndDot(String s){
if (s.isEmpty()) {
return “null”;
}
if(s.indexOf(".") > 0){
s = s.replaceAll(“0+?”, “”);//如最后一位是.则去掉
}
return s;
}/**
• 复制excel表格,该excel表格的格式应该是.xls
• @param modelExcel 模板excel文件的路径
• @param newExcel 新复制的excel文件需要保存的路径
• @param newName 新复制的excel文件的文件名
*/
public static void copyExcel(String modelExcel, String newExcel,String newName) {
HSSFWorkbook wb = null;
FileInputStream fis = null;
FileOutputStream fos = null;
try {File file=new File(newExcel);
if(!file.exists()){
file.mkdirs();
}
fis = new FileInputStream(modelExcel);
fos = new FileOutputStream(newExcel+"/"+newName);
wb = new HSSFWorkbook(fis);
wb.write(fos);} catch (Exception e) {
logger.info(“复制excel表格异常1:” + e.getMessage());
} finally {
try {
if (fis != null) {
fis.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
logger.info(“复制excel表格异常2:” + e.getMessage());
}
}
}/* public static void main(String[] args) {
try {List<AliVo> list = new ArrayList<>();
for (int i = 0; i <10; i++) {
AliVo aliVo = new AliVo();
aliVo.setId("id"+i);
aliVo.setName("name"+i);
aliVo.setRemark("remark"+i);
aliVo.setAliPhone("phone"+i);
aliVo.setMoney("money"+i);
list.add(aliVo);
}
System.out.println(list);
//模板文件的绝对路径
String modelExcel = "D:\\aaa\\haha.xls";
String fileName="newfile.xls";
//复制模板
NewExcelUtils.copyExcel(modelExcel, "D:\\aaa\\",fileName);
//新文件的路径
fileName="D:\\aaa\\"+fileName;
//往文件中写数据
NewExcelUtils.appendDateToExcel(fileName, list, AliVo.class, 2, 5);
//此处隐藏核心业务
} catch (Exception e) {
System.out.println(e);
}
}*/}
Controller层
List aliVoList =自己查询出来的数据try {
if(CollectionUtils.isEmpty(aliVoList)) aliVoList =new ArrayList<>();
//模板文件的绝对路径
String modelExcel = Test.class.getClassLoader().getResource(“excel/ali.xls”).getPath();
String url =Test.class.getClassLoader().getResource(“excel/”).getPath();
String orderNo = getOrderNo();
String fileName=orderNo+".xls";
//复制模板
NewExcelUtils.copyExcel(modelExcel, url,fileName);
//新文件的路径
fileName=url+fileName;
//往文件中写数据
NewExcelUtils.appendDateToExcel(fileName, aliVoList, AliVo.class, 2, 5);
//此处隐藏核心业务
String excelName =fileName;
this.exportExcel(orderNo,excelName);
} catch (Exception e) {
e.printStackTrace();
}//下载excel
public void exportExcel(String menuName,String excelName){
//导出的excel名称
byte[] buff = new byte[1024];
BufferedInputStream bis = null;
OutputStream os = null;
try {
HttpServletResponse response = getResponse();
response.addHeader(“Content-Disposition”,
“attachment;filename=” + new String(menuName.getBytes(“gb2312”), “ISO8859-1”) + “.xls”);
os = response.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(excelName));
int i = 0;
while ((i = bis.read(buff)) != -1) {
os.write(buff, 0, i);
os.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}