Java 导入导出功能总结


项目中经常需要使用导入导出功能来加快数据的操作,尤其是一些项目的后台管理系统,特此总结了下封装的的导入导出功能代码。

准备工作:pom中加入以下依赖

 <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.15-beta2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.15-beta2</version>
        </dependency>

导入功能

基本思路:

读取到文件--->创建表格并把文件流内容读取到表格中--->解析表格--->持久化

package com.simons.cn.springbootdemo.util;

import com.simons.cn.springbootdemo.bean.Movie;
import com.simons.cn.springbootdemo.service.Weixin.IndexService;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

@Service
public class FilePortUtil {
    private static final Logger log = LoggerFactory.getLogger(FilePortUtil.class);

    @Autowired
    private IndexService indexService;

    /**
     * 导入功能
     *
     * @param multipartFile
     * @return
     */
    public int fileImport(MultipartFile multipartFile) {
        File file = null;
        Workbook workbook = null;
        int totalNum = 0;
        /*得到的path是 /D:/springbootdemo/target/springbootdemo/WEB-INF/classes/  */
        String path = FilePortUtil.class.getClassLoader().getResource("/").getPath();
        /*拼接后的path就是 /D:/springbootdemo/target/springbootdemo/WEB-INF/电影正式资源.xlsx /*/
        path = path.substring(0, path.indexOf("WEB-INF") + "WEB-INF".length()) + "/" + multipartFile.getOriginalFilename();
        file = new File(path);
        try {
            /*把文件流copy读取到文件中*/
            FileCopyUtils.copy(multipartFile.getBytes(), file);
            workbook = WorkbookFactory.create(new FileInputStream(file));
            List<Movie> list = new ArrayList<>();
            /*遍历sheet页*/
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                Sheet sheet = workbook.getSheetAt(i);
                if (sheet == null) {
                    continue;
                }
                /*统计导入的总条数,要是你的excell包含了表头,就不用加1了*/
                if (sheet.getLastRowNum() > 0) {
                    totalNum += sheet.getLastRowNum() + 1;
                }
                /*遍历行,这里j的初始值取1是因为我的表格里第一行是表头*/
                for (int j = 1; j < sheet.getPhysicalNumberOfRows(); j++) {
                    Row row = sheet.getRow(j);
                    /*解析列,下标从0开始*/
                    Cell cell2 = row.getCell(2);
                    Cell cell3 = row.getCell(3);
                    if (cell2 == null || cell3 == null) {
                        continue;
                    }
                    String name = this.getCellValue(cell2);
                    String original = this.getCellValue(cell3);

                    /*我这里省略了很多数据清洗、校验的代码*/
                    
                    Movie movie = new Movie();
                    movie.setName(name);
                    movie.setOriginal(original);
                    list.add(movie);
                }
                /*持久化:批量新增*/
                indexService.insertBatch(list);
            }
            /*解析完删除此路径下的文件*/
            file.delete();
            return totalNum;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("导入功能公用类异常exception={}", e);
        }
        return totalNum;
    }

    public String getCellValue(Cell cell) {
        if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
            return String.valueOf(cell.getBooleanCellValue());
        } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
            Double d = cell.getNumericCellValue();
            return String.valueOf(d.intValue());
        }
        return String.valueOf(cell.getStringCellValue());
    }
    
}
一般来说,每个导入功能处理的逻辑不太一样,里面的校验、数据对象也不太一样,所以我这里就没有封装成公用类而仅仅写成service。


导出功能

基本思路:

创建表格对象--->将数据set进表格--->将表格流写入response

package com.simons.cn.springbootdemo.util;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.poi.hssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

@Service
public class FilePortUtil {
    private static final Logger log = LoggerFactory.getLogger(FilePortUtil.class);

    /**
     * 导出功能
     * 注意:泛型T类字段名和containBean集合里字段名字的一致性
     *
     * @param response
     * @param title       表名
     * @param headers     表头
     * @param list        数据集
     * @param containBean 数据集类型字段
     * @param <T>
     * @throws Exception
     */
    public static <T> void exportExcel(HttpServletResponse response, String title, String[] headers, List<T> list, List<String> containBean) throws Exception {
        HSSFWorkbook workbook = null;
        try {
            workbook = new HSSFWorkbook();
            HSSFSheet sheet = workbook.createSheet(title);
            HSSFRow row = sheet.createRow(0);
            /*创建第一行表头*/
            for (short i = 0; i < headers.length; i++) {
                HSSFCell cell = row.createCell(i);
                HSSFRichTextString text = new HSSFRichTextString(headers[i]);
                cell.setCellValue(text);
            }
            Iterator<T> it = list.iterator();
            int index = 0;
            while (it.hasNext()) {
                index++;
                row = sheet.createRow(index);
                T t = (T) it.next();
                /*反射得到字段*/
                Field[] fields = t.getClass().getDeclaredFields();
                /*如果需要匹配*/
                if (CollectionUtils.isNotEmpty(containBean)) {
                    for (int j = 0; j < containBean.size(); j++) {
                        for (int i = 0; i < fields.length; i++) {
                            Field field = fields[i];
                            if (!field.getName().equals(containBean.get(j)))
                                continue;
                            /*给每一列set值*/
                            setCellValue(t, field, row, j);
                        }
                    }
                } else {
                    for (int i = 0; i < fields.length; i++) {
                        Field field = fields[i];
                        setCellValue(t, field, row, i);
                    }
                }
            }
            /*application/vnd.ms-excel告诉浏览器要下载的是个excel*/
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            /*请求头设置,Content-Disposition为下载标识,attachment标识以附件方式下载*/
            response.addHeader("Content-Disposition", "attachment;filename=" + new String((title).getBytes(), "ISO8859-1") + ".xls");
            workbook.write(response.getOutputStream());
        } finally {
            if (workbook != null) {
                workbook.close();
            }
        }
    }

    /**
     * 设置每一行中的列
     *
     * @param t
     * @param field
     * @param row
     * @param index
     * @param <T>
     */
    private static <T> void setCellValue(T t, Field field, HSSFRow row, int index) {
        HSSFCell cell = row.createCell(index);
        Object value = invoke(t, field);
        String textValue = null;
        if (value != null) {
            if (value instanceof Date) {
                Date date = (Date) value;
                textValue = DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss");
            } else {
                textValue = value.toString();
            }
        }
        if (textValue != null) {
            cell.setCellValue(textValue);
        }
    }

    /**
     * 反射映射数据集字段
     *
     * @param t
     * @param field
     * @param <T>
     * @return
     */
    private static <T> Object invoke(T t, Field field) {
        try {
            String fieldName = field.getName();
            PropertyDescriptor pd = new PropertyDescriptor(fieldName, t.getClass());
            Method method = pd.getReadMethod();
            return method.invoke(t);
        } catch (Exception e) {
            return null;
        }
    }

    /*导出使用方式举例:
   String[] headers = new String[]{"积分商城订单号", "商品编码", "商品名称", "电子券号", "电子券金额", "电子券下发时间", "兑换手机", "消费金额", "消费状态"};

    List<String> values = new ArrayList<>();
    values.add("orderId");
    values.add("itemId");
    values.add("title");
    values.add("vcode");
    values.add("price");
    values.add("giveTime");
    values.add("phone");
    values.add("userAmount");
    values.add("isConsume");

    String title = "中国移动积分商城订单信息统计";
    List<PointsVirtualCodeInfoVo> list = ydjfService.getList(map);
    ExcelUtil.exportExcel(response,title,headers,list,values);*/

}

如上代码实际都能用,如有其它问题请留言~~

猜你喜欢

转载自blog.csdn.net/fanrenxiang/article/details/80985879