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,里面具体的逻辑交由程序员填充。


导出功能

导出功能是最常用的,下面的代码中用到了反射的思想,比如,你查询出来的List<T>结果集,只想导出指定的那些字段数据,就非常方便了,代码如下:


基本思路:创建表格对象--->将数据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;

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

    @ResponseBody
    @RequestMapping(value = "/fileport", method = RequestMethod.GET)
    public void filePort(HttpServletResponse response) {
        //导出的表名
        String title = "测试导出活动参与记录";
        //表中第一行表头字段
        String[] headers = {"主键id", "用户名", "活动id", "奖品id", "中奖时间"};
        //实际数据结果集
        List<UserReward> listObject = userRewardDao.queryUserActivityInfo("2018shuangdan_act", "2018shuangdan_evt", "sdthanks");
        //具体需要写入excel需要哪些字段,这些字段取自UserReward类,也就是上面的实际数据结果集的泛型
        List<String> listColumn = Arrays.asList("id", "username", "actId", "rewardId", "winRewardTime");
        try {
            FilePortUtil.exportExcel(response, title, headers, listObject, listColumn);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

如上代码实际项目中都能使用,如有问题欢迎留言哈~


books 引申阅读: 使用quartz实现高级定制化定时任务(包含管理界面)

books 推荐阅读:elastic search搜索引擎实战demo:https://github.com/simonsfan/springboot-quartz-demo,分支:feature_es

已标记关键词 清除标记
相关推荐
Excel源代码,ExcelCreate.java导出类和ExcelRead.java导入类 用到的poi底层架包有poi-3.6-20091214.jar,poi-contrib-3.6-20091214.jar poi-scratchpad-3.6-20091214.jar ExcelRead.java文件导入类 Public void importExcel(String file)读取文件方法一,file指明要导入的文件路径。 public void importExcel (File file) 读取文件方法二,参数是file文件。 public void importExcel (InputStream filestream)读取文件方法三,参数是文件流。 public List readRow (int sheetNumber,int rows), 读取第几张工作表的第几行数据返回一个list. (工作表,起始行) ExcelCreate.java文件导出类 public ExcelCreate (),构造函数。 public void createSheet(String sheetName),创建工作表(工作表名称)。可创建多个工作表。 public static void setDefaultCellHighWidthInRange(short[] eachCellWidth, int high) 设置各列单元格宽度,eachCellWidth[]指定的列的列号,high设置的宽度。 public void addHeader (list rowvalues, Boolean isFilter)导入表头,list是保存表头的集合,isFilter是否过滤。 public void addRow (List rowvalues),数据的导入Excel方法, public void insertRow (List rowvalues,Int rowIndex),数据的导入Excel方法,给指定的行后追加一条数据。 public void delRow(int row) 删除指定的行。 Public void setSelect (int row,int cells,List cellvalue)给指定的列设置下拉列表,row是行号,cells 是列号,list是下拉列表的数据。 public void exportExcel (String file)导出文件的路径方法一,file是要导出数据的文件路径。 public void exportExcel (File file) 导出文件的路径方法二,file是要导出的文件。 public void exportExcel (OutputStream outputstream) 导出文件的路径方法三,outputstream是输出流。
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页