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