Java 导入导出功能总结

it2022-05-05  113

原文链接:https://blog.csdn.net/fanrenxiang/article/details/80985879

项目中经常需要使用导入导出功能来加快数据的操作,尤其是一些项目的后台管理系统,特此奉上我们项目中使用到导入导出代码,均可以实际使用。准备工作: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(); } }

最新回复(0)