Java POI导入/导出(规则/非规则)excel

Java使用poi组件导出excel报表,能导出excel报表的还可以使用jxl组件,但jxl想对于poi功能有限,jxl应该不能载excel插入浮动层图片,poi能很好的实现输出excel各种功能,介绍poi导出excel功能实现案例,算比较常用的功能实现以及导出excel需要注意的地方。

环境配置

这里使用的为3.17版本的poi

        
            org.apache.poi
            poi-ooxml
            3.17
        
        
            org.apache.poi
            poi-ooxml-schemas
            3.17
        

一、导出模板

这里我们就不多BB了,直接上代码

所需util

package com.ecb.userCenter.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;

/**
 * @author Zuo Ning
 * @date 2019/7/24 16:24
 * @des 导出excel模板
 */
@Slf4j
public class ExcelUtils {
    public static void exportExcelUsers(HttpServletResponse response, String[] handers, String excleName) throws Exception {
        try {
            HSSFWorkbook wb = new HSSFWorkbook();
            HSSFSheet sheet = wb.createSheet("sheet1");
            HSSFCellStyle style = disFont(wb);
            HSSFRow rowFirst = sheet.createRow(0);
            rowFirst.setHeight((short) 300);
            // 设置列宽
            for (int i = 0; i < handers.length; i++) {
                sheet.setColumnWidth((short) i, (short) 8300);
            }
            for (int i = 0; i < handers.length; i++) {
                HSSFCell cell = rowFirst.createCell(i);
                cell.setCellStyle(style);
                cell.setCellValue(handers[i]);
            }
            //写出文件(path为文件路径含文件名)
            OutputStream output = response.getOutputStream();
            response.reset();
            response.setHeader("Content-disposition", "attachment; filename=" + excleName + ".xls");
            response.setContentType("application/msexcel");
            wb.write(output);
            output.close();
        } catch (Exception e) {
            log.error(e.getMessage());
            throw e;
        }
    }

   /**
     * 设置excel样式 
     *
     * @param wb
     * @return
     */
    public static HSSFCellStyle disFont(HSSFWorkbook wb) {
        HSSFCellStyle style = wb.createCellStyle();
        style.setBorderBottom(BorderStyle.THIN);//下边框
        style.setBorderLeft(BorderStyle.THIN);//左边框
        style.setBorderRight(BorderStyle.THIN);//右边框
        style.setBorderTop(BorderStyle.THIN); //上边框
        style.setAlignment(HorizontalAlignment.CENTER);//水平居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setFillForegroundColor(IndexedColors.WHITE.index);
        HSSFFont font = wb.createFont();
//        font.setFontName("华文行楷");//设置字体名称
        font.setFontHeightInPoints((short) 10);//设置字号
        font.setItalic(false);//设置是否为斜体
        font.setBold(true);//设置是否加粗
        style.setFont(font);
        return style;
    }
}

servie层

//service实现层

    public void exportWhitelistTemplate(HttpServletResponse response) {
        try {
            String time = DateUtils.getDate4yyyymmddhhmmss();
            String excelName = java.net.URLEncoder.encode("用户白名单模板-" + time, "UTF-8");
            String[] handers = {"姓名", "手机号"};
            // 1导入硬盘
            ExcelUtils.exportExcelUsers(response, handers, excelName);
        } catch (Exception e) {
            log.error(e.getMessage());
            Result.fail(ResultCode.EXCEPTION_OTHER.getCode(), "导出失败");
        }
    }

controller层

//controller层
    @GetMapping("/exportWhitelistTemplate")
    @ApiOperation("导出用户白名单模板")
    @IgnoreToken
    public Result exportWhitelistTemplate(HttpServletResponse response) {
        userWhitelistService.exportWhitelistTemplate(response);
        return null;
    }

导出后样式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-93DXCwwN-1578555718786)(http://39.105.146.77:5927/upload/2020/1/4-d8a0297ad0c349158d0f63119a12d3f7.png)]

这里可以根据自己需求更改handers从而完成自己的需求

二、导出

这里是导出带数据的,并且可以根据需求做一些处理

@Override
    public void redemptionPackageDownLoad(HttpServletResponse response, OilCardLedgerQueryParameters params) {
        JSONObject result = new JSONObject();
        try {
            Example example = new Example(UserOilCardOrderJournal.class);
            Example.Criteria criteria = example.createCriteria();
            //1.1 用户账户筛选
            boolean userAccount = StringUtils.isNotEmpty(params.getUserAccount());
            if (userAccount) {
                criteria.andEqualTo("userAccount", params.getUserAccount());
            }

            //1.2 根据时间段筛选 (前端传来startTime和endTime)
            boolean startTime = StringUtils.isNotEmpty(params.getStartTime());
            boolean endTime = StringUtils.isNotEmpty(params.getEndTime());
            if (startTime && endTime) {
                criteria.andBetween("subTime", params.getStartTime(), params.getEndTime());
            }
            //1.3 根据来源进行筛选 需要判空
            if (params.getSource() != null) {
                criteria.andEqualTo("source", params.getSource());
            }
            //1.4 根据订单编号进行筛选 需要判空
            if (StringUtils.isNotEmpty(params.getOrderCode())) {
                criteria.andEqualTo("orderCode", params.getOrderCode());
            }
            //1.5 根据网店编号进行筛选 需要判空
            if (StringUtils.isNotEmpty(params.getShopCode())) {
                criteria.andEqualTo("shopCode", params.getShopCode());
            }
            //1.6 根据应用名称或易捷网店名称进行筛选 需要判空
            if (StringUtils.isNotEmpty(params.getAppName())) {
                criteria.andEqualTo("appName", params.getAppName());
            }

            //1.7 排序,前端不传参数时默认按照createTime降序排序
            if (params.getSortBy() == null) {
                example.orderBy("subTime").desc();
            } else {
                example.setOrderByClause(params.getSortBy() + (params.getDesc() ? " DESC" : " ASC"));
            }

            List list = oilCardOrderJournalMapper.selectByExample(example);
            List subList = null;
            if (list.size() > REDEMPTION_PACKAGE_NUMBER) {
                subList = list.subList(0, 1000);
            } else {
                subList = list;
            }
            String time = DateUtils.getDate4yyyymmddhhmmss();
            String excelName = java.net.URLEncoder.encode("兑换包列表-" + time, "UTF-8");
            String[] handers = {"序号", "用户账号", "充值日期", "充值类型", "充值金额", "订单金额", "订单编号", "网店编码", "网点名称"};
            // 1导入硬盘
            exportExcelToDisk(response, handers, subList, excelName);
        } catch (Exception e) {
            log.error(e.getMessage());
            result.put("", "对不起,下载失败");
        }
    }

这里根据产品需求 进行设置

 private void exportExcelToDisk(HttpServletResponse response, String[] handers, List list, String excleName) throws Exception {
        try {
            HSSFWorkbook wb = new HSSFWorkbook();
            HSSFSheet sheet = wb.createSheet("sheet1");
            HSSFCellStyle style = ExcelUtils.disFont(wb);
            HSSFRow rowFirst = sheet.createRow(0);
            rowFirst.setHeight((short) 500);
            // 设置列宽
            for (int i = 0; i < handers.length; i++) {
                sheet.setColumnWidth((short) i, (short) 5000);
            }
            for (int i = 0; i < handers.length; i++) {
                HSSFCell cell = rowFirst.createCell(i);
                cell.setCellStyle(style);
                cell.setCellValue(handers[i]);
            }
            for (int i = 0; i < list.size(); i++) {
                UserOilCardOrderJournal fr = list.get(i);
                String source = "";
                if (fr.getSource() == 0) {
                    source = "线上购物";
                }
                if (fr.getSource() == 1) {
                    source = "线下购物";
                }
                if (fr.getSource() == 2) {
                    source = "新人大礼包";
                }
                if (fr.getSource() == 3) {
                    source = "分享App";
                }
                if (fr.getSource() == 4) {
                    source = "分享商品";
                }
                if (fr.getSource() == 5) {
                    source = "分享订单";
                }
                if (fr.getSource() == 6) {
                    source = "金采订单";
                }
                if (fr.getSource() == 7) {
                    source = "零售加油(核销指定券后赠送)";
                }
                if (fr.getSource() == 8) {
                    source = "游戏奖励";
                }
                if (fr.getSource() == 9) {
                    source = "保险返利";
                }
                HSSFRow row = sheet.createRow(i + 1);
                row.setHeight((short) 400);
                row.createCell(0).setCellValue(i + 1);
                if (fr.getUserAccount() != null) {
                    row.createCell(1).setCellValue(fr.getUserAccount());
                }
                if (fr.getSubTime() != null) {
                    row.createCell(2).setCellValue(DateUtils.formatDateTime(fr.getSubTime()));
                }
                if (fr.getSource() != null) {
                    row.createCell(3).setCellValue(source);
                }
                if (fr.getGiveMoney() != null) {
                    row.createCell(4).setCellValue(fr.getGiveMoney().toString());
                }
                if (fr.getOrderMoney() != null) {
                    row.createCell(5).setCellValue(fr.getOrderMoney().toString());
                }
                if (fr.getOrderCode() != null) {
                    row.createCell(6).setCellValue(fr.getOrderCode());
                }
                if (fr.getShopCode() != null) {
                    row.createCell(7).setCellValue(fr.getShopCode());
                }
                if (fr.getAppName() != null) {
                    row.createCell(8).setCellValue(fr.getAppName());
                }
            }
            //写出文件(path为文件路径含文件名)
            OutputStream output = response.getOutputStream();
            response.reset();
            response.setHeader("Content-disposition", "attachment; filename=" + excleName + ".xls");
            response.setContentType("application/msexcel");
            wb.write(output);
            output.close();
        } catch (Exception e) {
            log.error(e.getMessage());
            throw e;
        }
    }

controller层

   @ApiOperation(value = "导出兑换包信息")
    @GetMapping("/downLoad")
    @IgnoreToken
    public void downLoad(HttpServletResponse response,
                         @RequestParam(value = "userAccount", required = false) String userAccount,
                         @RequestParam(value = "startTime", required = false) String startTime,
                         @RequestParam(value = "endTime", required = false) String endTime,
                         @RequestParam(value = "source", required = false) Integer source,
                         @RequestParam(value = "orderCode", required = false) String orderCode,
                         @RequestParam(value = "shopCode", required = false) String shopCode,
                         @RequestParam(value = "appName", required = false) String appName) {
        OilCardLedgerQueryParameters params = new OilCardLedgerQueryParameters(userAccount, startTime, endTime, source, orderCode, shopCode, appName);
        oilCardExchangeService.redemptionPackageDownLoad(response, params);
    }

导出效果图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t1Q6pKs1-1578555718787)(http://39.105.146.77:5927/upload/2020/1/1-6e16a93b0ac9421a879f985597ed7077.png)]

三、导入并存入数据库

service层

 @Override
    public boolean importWhitelist(MultipartFile file) throws IOException {
        ExcelReader reader = ExcelUtil.getReader(file.getInputStream(), 0);
        // 跳过标题从第一行读取数据
        List> readAllResult = reader.read(1);
        for (List objects : readAllResult) {
            this.filterNullContent(objects);
        }

        List list = new ArrayList<>();

        for (List objects : readAllResult) {
            String name = String.valueOf(objects.get(0));
            String mobilePhone = String.valueOf(objects.get(1));
            UserWhitelist userWhitelist = new UserWhitelist();
            userWhitelist.setUsername(name);
            userWhitelist.setMobilePhone(mobilePhone);
            userWhitelist.setStatus(Boolean.TRUE);
            userWhitelist.setCreateTime(new Timestamp(System.currentTimeMillis()));
            userWhitelist.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            list.add(userWhitelist);
        }
        return saveUserWhiteLists(list);
    }

 
  

过滤空的内容(可省略)

    /**
     * 过滤空的内容
     *
     * @param objects 每一行数据数据
     * @author
     */
    private void filterNullContent(List objects) {
        // 0 是序号
        String name = String.valueOf(objects.get(0));
        String mobilePhone = String.valueOf(objects.get(1));
        if (StringUtils.isEmpty(name)) {
            throw new BusinessException("会员姓名不能为空");
        }
        if (StringUtils.isEmpty(mobilePhone)) {
            throw new BusinessException("会员手机号不能为空");
        }
    }
 
  

四、导入不规则excel

需导入的数据
这里就用一个demo来模拟一下不规则excel的导入

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7W49FJR1-1578555718787)(http://39.105.146.77:5927/upload/2020/1/2-73a6f90ab5424666b7052344315c989d.png)]
在实际开发中碰到脑路清奇的产品,就会出现这种需求,这种不规则的excel,目前我的思路是将没有规律的每行读出来,根据下标索引去定位数据(缺点:模板格式必须严格按照规定,不然数据会出现异常)。思路比较笨,仅供参考。借鉴一下还是可以的,如有更好的方法,请不要吝啬,告知一下!
这里就用一个demo来模拟一下不规则excel的导入

** utill **

package com.usercenter.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
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 org.springframework.web.multipart.MultipartFile;

public class POIUtils {
	
	
	private final static String XLS = "xls";
	private final static String XLSX = "xlsx";
	
	public static List readExcel(MultipartFile formFile) throws IOException{
		//检查文件
		checkFile(formFile);
		//获得工作簿对象
		Workbook workbook = getWorkBook(formFile);
		//创建返回对象,把每行中的值作为一个数组,所有的行作为一个集合返回
		List list = new ArrayList<>();
		if(null!=workbook){
			for(int sheetNum = 0;sheetNum
public static void main(String[] args) throws IOException {

        File productFile = new File("C:\\Users\\16601\\Desktop\\aa.xlsx");

        FileInputStream inputStream = new FileInputStream(productFile);

        MultipartFile excelFile = new MockMultipartFile("file", "C:\\Users\\16601\\Desktop\\" + productFile.getName(), "text/plain", IOUtils.toByteArray(inputStream));

        List rowList = POIUtils.readExcel(excelFile);
        SalesOrderVo salesOrderVo = new SalesOrderVo();

        //基本信息第一行
        String[] basicInformationOne = rowList.get(1);
        salesOrderVo.setClienteleName(basicInformationOne[1]);
        salesOrderVo.setClienteleCode(basicInformationOne[3]);
        salesOrderVo.setReceiptUser(basicInformationOne[7]);
        //基本信息第二行
        String[] basicInformationTwo = rowList.get(2);
        salesOrderVo.setBusinessType(basicInformationTwo[1]);
        salesOrderVo.setSalesDepartment(basicInformationTwo[3]);
        salesOrderVo.setSalesPersonnel(basicInformationTwo[7]);
        //基本信息第三行
        String[] basicInformationThree = rowList.get(3);
        salesOrderVo.setDeliveryTime(SimpleDate(basicInformationThree[1]));
        salesOrderVo.setDeliveryType(basicInformationThree[3]);
        salesOrderVo.setOrderTime(SimpleDate(basicInformationThree[7]));

        //产品列表
        //产品列表倒数第二行
        String[] productListTwo = rowList.get(rowList.size() - 7);
        salesOrderVo.setOrdersTotalAmount(productListTwo[1]);
        salesOrderVo.setOrdersTotalDiscount(productListTwo[3]);
        salesOrderVo.setSquaresTotal(productListTwo[7]);
        salesOrderVo.setNumberTotal(productListTwo[9]);
        //产品列表倒数第一行
        String[] productListOne = rowList.get(rowList.size() - 6);
        salesOrderVo.setBusinessManager(productListOne[1]);
        salesOrderVo.setPaymentType(productListOne[3]);
        salesOrderVo.setTotalQuantity(productListOne[7]);

        // 物流信息
        // 物流信息第一行
        String[] logisticsInformationOne = rowList.get(rowList.size() - 4);
        salesOrderVo.setDeliveryTime(SimpleDate(logisticsInformationOne[1]));
        salesOrderVo.setReceiptTime(SimpleDate(logisticsInformationOne[3]));
        // 物流信息第二行
        String[] logisticsInformationTwo = rowList.get(rowList.size() - 3);
        salesOrderVo.setReceiptAddress(logisticsInformationTwo[1]);
        salesOrderVo.setReceiptUser(logisticsInformationTwo[3]);
        // 物流信息第三行
        String[] logisticsInformationThree = rowList.get(rowList.size() - 2);
        salesOrderVo.setReceiptPhone(logisticsInformationThree[1]);
        salesOrderVo.setTransportInfo(logisticsInformationThree[3]);
        //备注行
        String[] logisticsInformationFour = rowList.get(rowList.size() - 1);
        salesOrderVo.setRemark(logisticsInformationFour[1]);

        ArrayList list = new ArrayList<>();
        //动态获取规则数据
        for (int i = 6; i < rowList.size() - 7; i++) {
            OrderproduceVo orderproduceVo = new OrderproduceVo();
            String[] product = rowList.get(i);
            orderproduceVo.setOrderCode(product[0]);
            orderproduceVo.setProductCode(product[1]);
            orderproduceVo.setProductName(product[2]);
            orderproduceVo.setProductUnit(product[3]);
            orderproduceVo.setProductNum(Integer.parseInt(product[4]));
            orderproduceVo.setPrice(product[5]);
            orderproduceVo.setDiscount(product[6]);
            orderproduceVo.setAmount(product[7]);
            orderproduceVo.setNumber(product[8]);
            orderproduceVo.setSquareNumber(product[9]);
            orderproduceVo.setRemark(product[10]);
            list.add(orderproduceVo);
        }
        salesOrderVo.setProduces(list);

        JSONObject result = JSONObject.parseObject(JSON.toJSONString(salesOrderVo));

        System.out.println(result);
    }

    /**
     * 格式化导入时间
     *
     * @param s
     * @return
     */
    private static String SimpleDate(String s) {
        Date StartDate = HSSFDateUtil.getJavaDate(Double.valueOf(s));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = sdf.format(StartDate);
        return format;
    }
}

输出结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LcMAVYLM-1578555718787)(http://39.105.146.77:5927/upload/2020/1/3-924bef1a9f6e419d8c3cc2de7e34d469.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pSh3WImN-1578555718788)(http://39.105.146.77:5927/upload/2020/1/4-512dfd9ac5e141e0bd9249ccc29d56d2.png)]

格式化导入时间是用来解决java读取之后把时间转为了距离1990年1月1号的天数,比如excel中时间为2018/9/16 18:30,java读取之后变成43359.77083就会有问题。

到这里全套的导入导出就完成了,供各位参考…

你可能感兴趣的:(java)