Springboot之Excel表格导出

简介: Springboot之Excel表格导出

Springboot之Excel表格导出

表格导出使用的还是POI,POI的介绍请查看

https://blog.csdn.net/qq_36654629/article/details/90172911

使用前需引入poi相关依赖

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

表格导出工具

import org.apache.poi.hssf.usermodel.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;
@Service
@Transactional(rollbackFor = Throwable.class)
public class GoodsExportService {
/**
     * @param sheetName sheet标签名称,headers第一行标题名称,list 数据
     * @author 
     * @description excel 导出
     * @date 2019-06-27
     * @throws IOException
     */
    public void exportTemplate(HttpServletResponse response, String sheetName, String[] headers, List list) throws IOException {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet(sheetName);
        setTitle(headers,workbook, sheet);
        //新增数据行,并且设置单元格数据
        for(int i=0;i<list.size();i++){
            List clist = (List)list.get(i);
            HSSFRow hssfRow = sheet.createRow(i+1);
            for(int j=0;j<clist.size();j++){
                hssfRow.createCell(j).setCellValue((String)clist.get(j));
            }
        }
        Date date = new Date();
        String fileName =String.valueOf(date.getTime());
        fileName = fileName + ".xls";
        //清空response
        response.reset();
        //设置response的Header
        response.setContentType("application/vnd.ms-exce;charset=GBK");
        response.setCharacterEncoding("GBK");
        response.setHeader("content-Disposition", "attachment;filename="+ java.net.URLEncoder.encode(new String(fileName.getBytes("GBK"),"ISO-8859-1"), "GBK"));
        response.setDateHeader("Expires", 0);
        OutputStream os = new BufferedOutputStream(response.getOutputStream());
        //将excel写入到输出流中
        workbook.write(os);
        os.flush();
        os.close();
    }
    // 创建表头
    public void setTitle(String[] headers,HSSFWorkbook  workbook, HSSFSheet sheet) {
        HSSFRow row = sheet.createRow(0);
        // 设置为居中加粗
        HSSFCellStyle style = workbook.createCellStyle();
        HSSFFont font = workbook.createFont();
        style.setFont(font);
        // 设置表格默认列宽度为15个字节
        for (int i = 0; i < headers.length; i++) {
            HSSFCell cell = row.createCell(i);
            HSSFRichTextString text = new HSSFRichTextString(headers[i]);
            cell.setCellValue(text);
            cell.setCellStyle(style);
        }
    }
}

表格导入

@Service
@Transactional(rollbackFor = Throwable.class)
public class GoodsImportService {
    @Value("${image.uploadPath}")
    private String imageUploadPath;
    @Autowired
    private CustomGoodsUnitService customGoodsUnitService;
    @Autowired
    private CustomMerchantInfoService customMerchantInfoService;
    @Autowired
    private CustomGoodsCategoryService customGoodsCategoryService;
    /**
     * 批量导入商品专用
     *
     * @throws IOException
     * @author liyueken
     * @description excel 导入
     * @date 2019-06-27
     */
    public List analysisExcelByGoods(HttpServletRequest request, MultipartFile file, String userId, MerchantInfo info, Boolean updownState) throws IOException, InvalidFormatException {
        Workbook wb = readExcel(request, file);//读取
        Sheet sheet = null;
        Row row = null;
        List<Goods> list = null;
        if (wb != null) {
            //用来存放表中数据
            list = new ArrayList<>();
            //获取第一个sheet
            sheet = wb.getSheetAt(0);
            //获取最大行数
            int rownum = sheet.getLastRowNum();
            for (int i = 0; i < rownum; i++) {
                //从第二行开始
                row = sheet.getRow(i + 1);
                if (row != null) {
                    //第一个单元格为空,定义为最后一行
                    if (row.getCell(0) == null) {
                        return list;
                    }
                    Goods goods = new Goods();
                    goods.setId(UUIDUtils.generator());
                    goods.setCreateUser(userId);
                    goods.setLastModifyUser(userId);
                    goods.setMerchantId(info.getId());
                    goods.setMerchantName(info.getCompanyName());
                    goods.setState(true);
                    goods.setGoodsType(GoodsTypeEnum.NORMAL.getCode());
                    //设置Excel数据读入实体
                    goods.setGoodsName(getCellFormatValue(row.getCell(0)));
                    if (row.getCell(1) != null) {
                        goods.setGoodsDescription(getCellFormatValue(row.getCell(1)));
                    }
                    if (row.getCell(2) == null) {
                        throw new GenericException(GoodsErrorEnum.GOODS_CATEGORY.getCode(), GoodsErrorEnum.GOODS_CATEGORY.getDesc());
                    }
                    //=================================================
                    //-1表示不限制库存
                    goods.setGoodsInventory(new BigDecimal("-1"));
                    goods.setGoodsInventoryType(GoodsInventoryTypeEnum.UNRESTRICTED.getCode());
                    String categoryName = getCellFormatValue(row.getCell(2));
                    boolean flag = true;
                    String categoryFullName = "";
                    String categoryFullId = "";
                    String[] split = categoryName.split(",");
                    GoodsCategory goodsCategory = customGoodsCategoryService.getByName(split[0]);
                    if (goodsCategory == null) {
                        //商品分类不存在异常
                        throw new GenericException(GoodsCategoryErrorEnum.CATEGORY_ISEMPTY.getCode(), GoodsCategoryErrorEnum.CATEGORY_ISEMPTY.getDesc());
                    }
                    goods.setCategoryId(goodsCategory.getId());
                    //todo 待定
                    categoryFullName = goodsCategory.getCategoryName();
                    categoryFullId = goodsCategory.getId();
                    String pid = goodsCategory.getPid();
                    while (flag) {
                        GoodsCategory bean = customGoodsCategoryService.getEqualsIdByPid(pid);
                        if (bean == null) {
                            flag = false;
                        } else {
                            categoryFullName = bean.getCategoryName() + "," + categoryFullName;
                            categoryFullId = bean.getId() + "," + categoryFullId;
                            pid = bean.getPid();
                        }
                    }
                    goods.setCategoryFullId(categoryFullId);
                    goods.setCategoryFullName(categoryFullName);
                    goods.setGoodsOriginalPrice(new BigDecimal(getCellFormatValue(row.getCell(3))));
                    if (row.getCell(4) == null) {
                        throw new GenericException(GoodsErrorEnum.GOODS_UNIT_ISEMPTY.getCode(), GoodsErrorEnum.GOODS_UNIT_ISEMPTY.getDesc());
                    }
                    String goodsUnit = getCellFormatValue(row.getCell(4));
                    //校验单位是否符合平台规范
                    GoodsUnit goodsUnit1 = customGoodsUnitService.checkName(goodsUnit);
                    if (goodsUnit1 == null) {
                        throw new GenericException(GoodsErrorEnum.GOODS_UNIT_ISEMPTY.getCode(), GoodsErrorEnum.GOODS_UNIT_ISEMPTY.getDesc());
                    }
                    //设置商品单位编码
                    goods.setGoodsUnit(goodsUnit);
                    goods.setGoodsUnitCode(goodsUnit1.getCode());
                    goods.setGoodsMinUnit(Integer.valueOf((row.getCell(5).getStringCellValue())));
                    goods.setGoodsSalesPrice(new BigDecimal(getCellFormatValue(row.getCell(6))));
                    goods.setAuditState(GoodsAuditStateEnum.AUDIT_OK.getCode());
                    goods.setIfShortage(false);//默认不缺货
                    goods.setUpdownState(updownState);
                    //0否1是  称重商品  默认false 0
                    goods.setIfWeighGoods(false);
                    if (row.getCell(9).getStringCellValue() == "1") {
                        goods.setIfWeighGoods(true);
                    }
                    goods.setSupplierId(row.getCell(10).getStringCellValue());
                    goods.setSupplierName(row.getCell(11).getStringCellValue());
                    try {
                        goods.setQualityGuaranteePeriod(DateUtils.format(row.getCell(12).getStringCellValue(),"yyyy/MM/dd"));
                    } catch (ParseException e) {
                        throw new GenericException(2011001,"日期转换异常");
                    }
                    if (row.getCell(13) != null) {
                        goods.setGoodsFirstPic(row.getCell(13).getStringCellValue());
                    } else {
                        throw new GenericException(GoodsErrorEnum.GOODS_FIRST_PIC_ISEMPTY_ISEMPTY.getCode(),
                                GoodsErrorEnum.GOODS_FIRST_PIC_ISEMPTY_ISEMPTY.getDesc());
                    }
                    list.add(goods);
                } else {
                    break;
                }
            }
        }
        return list;
    }
    /**
     * @param file 附件
     * @return 文件名称
     * @date 2019-6-27
     * @author zl
     * @description 读取附件
     */
    public Workbook readExcel(HttpServletRequest request, MultipartFile file) throws IOException, InvalidFormatException {
        String excelPath = upload(request, file);//上传excel文件
        File excel = new File(excelPath);
        InputStream in = new FileInputStream(excel);
        String fileName = excel.getName();
        Workbook wb = null;
        if (excel.isFile() && excel.exists()) {   //判断文件是否存在
            InputStream is = in;
            if (fileName.endsWith("xls")) {
                wb = new HSSFWorkbook(is);
            } else if (fileName.endsWith("xlsx")) {
                wb = WorkbookFactory.create(is);
            } else {
                throw new GenericException(AttachErrorEnum.ATTACH_TYPE_EXCEL_ERROR.getCode(), AttachErrorEnum.ATTACH_TYPE_EXCEL_ERROR.getDesc());
            }
        }
        return wb;
    }
    /**
     * @param file 附件
     * @return 文件名称
     * @date 2019-6-27
     * @author zl
     * @description 附件上传
     */
    public String upload(HttpServletRequest request, MultipartFile file) {
        List<FileBean> filePath = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        String folder = "" + cal.get(Calendar.YEAR) + (cal.get(Calendar.MONTH) + 1) + cal.get(Calendar.DATE);
        String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getRequestURI();
        String path = "";
        try {
            //todo 前端传递业务类型。判断能否上传
            String fullFileName = System.currentTimeMillis() + file.getOriginalFilename();
            String serveFileName = fullFileName.substring(0, fullFileName.lastIndexOf("."));
            String originalName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."));
            path = imageUploadPath + File.separator + folder + File.separator + fullFileName;
            File target = new File(path);
            if (!target.getParentFile().exists()) {
                target.getParentFile().mkdirs();
            }
            file.transferTo(target);
            String fileResource = basePath + "/" + folder + "/" + fullFileName;
            //信息封装
            FileBean fileBean = new FileBean(fullFileName, originalName, fileResource, file.getContentType());
            //返回文件在服务器的地址
            filePath.add(fileBean);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return path;
    }
    public static String getCellFormatValue(Cell cell) {
        String cellValue = null;
        if (cell != null) {
            //判断cell类型
            switch (cell.getCellType()) {
                case Cell.CELL_TYPE_NUMERIC: {
                    cellValue = String.valueOf(cell.getNumericCellValue());
                    break;
                }
                case Cell.CELL_TYPE_FORMULA: {
                    //判断cell是否为日期格式
                    if (DateUtil.isCellDateFormatted(cell)) {
                        //转换为日期格式YYYY-mm-dd
//                        cellValue = cell.getDateCellValue();
                        cellValue = String.valueOf(cell.getNumericCellValue());
                    } else {
                        //数字
                        cellValue = String.valueOf(cell.getNumericCellValue());
                    }
                    break;
                }
                case Cell.CELL_TYPE_STRING: {
                    cellValue = cell.getRichStringCellValue().getString();
                    break;
                }
                default:
                    cellValue = "";
            }
        } else {
            cellValue = "";
        }
        return cellValue;
    }
}

业务层实现导出具体业务

@Service
@Transactional(rollbackFor = Throwable.class)
public class MerchantGoodsService extends GoodsService {
    @Autowired
    private MerchantGoodsDao merchantGoodsDao;
    @Autowired
    private MerchantMerchantInfoService merchantMerchantInfoService;
    @Autowired
    @Qualifier("goodsMapStructImpl")
    private GoodsMapStruct goodsMapStruct;
    @Autowired
    private CustomMerchantInfoService customMerchantInfoService;
    @Autowired
    private GoodsExportService excelExport;
    /**
     * @Description: 批量导入商品
     * @Param: []
     * @return: void
     * @Author:
     * @Date: 2019/6/29
     */
    public void batchImport(HttpServletRequest request, MultipartFile file, String userId) throws IOException, InvalidFormatException {
        //卖家
        MerchantInfo info = customMerchantInfoService.getByUserId(userId);
        //卖家添加商品默认下架状态
        List<Goods> list = excelImport.analysisExcelByGoods(request, file, userId, info, false);
        //插入
        merchantGoodsDao.batchInsert(list);
    }
    /**
     * @Description: 批量导出商品逻辑
     * @Param: [vo, response, userId]
     * @return: void
     * @Author: 
     * @Date: 2019/7/15
     */
    public void batchExport(GoodsQueryVo vo, HttpServletResponse response, String userId) throws IOException {
        //表头headers
        String[] headers = {"商品名(可修改)", "商品描述(可修改)", "所属分类", "原价", "基础单位",
                "最小销售规格", "销售价", "审核状态(可修改,0待审核,1审核通过,2审核失败,3暂存)", "销售状态(可修改,1上架,0下架)", "是否称重(可修改,1称重,0不称)",
                "供应商id", "供应商", "保质期", "首图url"};
//        获取所有当前卖家的未删除状态的商品
        List<Goods> goodsList = merchantGoodsDao.selectGoodsList(vo, userId);
        List<List<String>> target = new ArrayList();
        for (Goods goods : goodsList) {
            List<String> row = new ArrayList<>();
            row.add(goods.getGoodsName());
            row.add(goods.getGoodsDescription());
            row.add(goods.getCategoryFullName());
            row.add(String.valueOf(goods.getGoodsOriginalPrice()));
            row.add(goods.getGoodsUnit());
            row.add(String.valueOf(goods.getGoodsMinUnit()));
            row.add(String.valueOf(goods.getGoodsSalesPrice()));
            //审核状态
            Byte auditState = null;
            if (GoodsAuditStateEnum.AUDITING.getCode() == goods.getAuditState()) {
                auditState = GoodsAuditStateEnum.AUDITING.getCode();
            } else if (GoodsAuditStateEnum.AUDIT_FAIL.getCode() == goods.getAuditState()) {
                auditState = GoodsAuditStateEnum.AUDIT_FAIL.getCode();
            } else if (GoodsAuditStateEnum.AUDIT_OK.getCode() == goods.getAuditState()) {
                auditState = GoodsAuditStateEnum.AUDIT_OK.getCode();
            }else if (GoodsAuditStateEnum.TEMP_SAVE.getCode() == goods.getAuditState()){
                auditState = GoodsAuditStateEnum.TEMP_SAVE.getCode();
            }
            row.add(String.valueOf(auditState));
            //销售状态(上下架状态)
            Integer updown_state = null;
            if (goods.getUpdownState()) {
                updown_state = GoodsStateEnum.GOODS_ONLINE.getCode();
            } else {
                updown_state = GoodsStateEnum.GOODS_DOWNLINE.getCode();
            }
            row.add(String.valueOf(updown_state));
            //是否称重
            Byte ifWeight = null;
            if (goods.getIfWeighGoods()) {
                ifWeight = GoodsWeightEnum.WEIGHT.getCode();
            } else {
                ifWeight = GoodsWeightEnum.UN_WEIGHT.getCode();
            }
            row.add(String.valueOf(ifWeight));
            //供应商id 供应商 保质期 首图url
            row.add(goods.getSupplierId());
            row.add(goods.getSupplierName());
            if (goods.getQualityGuaranteePeriod() != null) {
                row.add(DateUtils.format(goods.getQualityGuaranteePeriod(), "yyyy/MM/dd"));
            }
            row.add(goods.getGoodsFirstPic());
            target.add(row);
        }
        String sheetName = "在售商品";
        excelExport.exportTemplate(response, sheetName, headers, target);
    }
}

商品导入控制层

@Controller
@RequestMapping("goods")
public class MerchantGoodsController extends GenericController {
    private static final Logger LOGGER = LoggerFactory.getLogger(MerchantGoodsController.class);
    @Autowired
    private FileService fileService;
    @Autowired
    private MerchantGoodsService merchantGoodsService;
    @Autowired
    private SecurityHandler securityHandler;
  /**
     * @Param [request, file]
     * @return com.hrt.framework.web.core.Result
     * @Author youjp
     * @Description //TODO 批量导入商品
     * @throw
     **/
    @PostMapping(value = "/goodsBatchImport")
    @ResponseBody
    public Result goodsBatchImport(HttpServletRequest request, MultipartFile file) throws IOException, InvalidFormatException {
        merchantGoodsService.batchImport(request, file, securityHandler.getUserId());
        return Result.success();
    }
   /**
     * @Param [response, vo]
     * @return void
     * @Author youjp
     * @Description //TODO 批量导出商品
     * @throw
     **/
    @GetMapping(value = "/goodsBatchExport")
    public void goodsBatchExport(HttpServletResponse response, GoodsQueryVo vo) throws IOException {
        merchantGoodsService.batchExport(vo, response, securityHandler.getUserId());
    }
}

前端接口请求:

  • Excel导出时,只要请求导出接口即可
  var url = window.mconfig.mbaseUrl + path.goodsBatchExport + "?access_token=" + access_token + "&goodsName=" + goodsName + "&categoryFullId=" + categoryFullId;
    window.location.href = url;

Excel导入:

  var uploadInst2 = upload.render({
          elem: '#batchUploadGoods', //绑定元素
          accept: 'file', //普通文件
          exts: 'xls|xlsx', //只允许上传压缩文件
          url: window.mconfig.mbaseUrl + path.goodsBatchImport + "?access_token=" + access_token, //上传接口
          done: function (res) {
            if (res.code == window.httpStatus.success) {
              layer.msg("导入成功", {
                icon: 6
              });
              table.reload('goodsTableId', {
                url: window.mconfig.mbaseUrl + path.page,
                async: false,
                request: {
                  pageName: 'pageNo', // 页码的参数名称,默认:page
                  limitName: 'pageSize' // 每页数据量的参数名,默认:limit
                },
                page: {
                  curr: 1
                },
              });
            } else {
              layer.alert('导入失败:' + res.msg, {
                icon: 0,
              });
            }
          },
          error: function () {
            layer.msg("请联系管理员", {
              icon: 5
            });
          },
          headers: { //通过 request 头传递
            Authorization: layui.data(setter.tableName)[setter.headers.accessTokenName]
          }
        });

页面代码:

      <div class="layui-input-inline">
              <button class="layui-btn layui-btn-normal" lay-filter="exportGoods" lay-submit="">
                <i class="layui-icon">&#xe641;</i>导出
              </button>
         </div>
     <div class="layui-btn layui-btn-sm" id="batchUploadGoods">
          <i class="layui-icon">&#xe61f;</i>批量导入
          <span id="batchUploadTag"></span>
        </div>

20200401134307494.png

更详细的可以看一下这篇博文:

https://blog.csdn.net/typ1805/article/details/83279532


相关文章
|
1月前
|
Java API Apache
Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
【10月更文挑战第29天】Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
118 5
|
16天前
|
前端开发
实现Excel文件和其他文件导出为压缩包,并导入
实现Excel文件和其他文件导出为压缩包,并导入
23 1
|
18天前
|
数据格式 UED
记录一次NPOI库导出Excel遇到的小问题解决方案
【11月更文挑战第16天】本文记录了使用 NPOI 库导出 Excel 过程中遇到的三个主要问题及其解决方案:单元格数据格式错误、日期格式不正确以及合并单元格边框缺失。通过自定义单元格样式、设置数据格式和手动添加边框,有效解决了这些问题,提升了导出文件的质量和用户体验。
123 3
|
29天前
|
SQL 数据可视化 数据挖掘
想让Excel表格设计更美观?试试这几款好用工具!
Excel表格设计在项目管理和数据分析中至关重要。本文推荐四款辅助工具:板栗看板、Excel自动图表助手、Think-Cell Chart 和 Power BI,分别在任务管理、图表生成、数据可视化等方面表现突出,帮助你设计出更专业、美观的表格。
50 2
|
1月前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
82 8
|
1月前
|
Java API Apache
|
1月前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
41 4
|
1月前
|
存储 easyexcel Java
SpringBoot+EasyExcel轻松实现300万数据快速导出!
本文介绍了在项目开发中使用Apache POI进行数据导入导出的常见问题及解决方案。首先比较了HSSFWorkbook、XSSFWorkbook和SXSSFWorkbook三种传统POI版本的优缺点,然后根据数据量大小推荐了合适的使用场景。接着重点介绍了如何使用EasyExcel处理超百万数据的导入导出,包括分批查询、分批写入Excel、分批插入数据库等技术细节。通过测试,300万数据的导出用时约2分15秒,导入用时约91秒,展示了高效的数据处理能力。最后总结了公司现有做法的不足,并提出了改进方向。
|
2月前
|
JavaScript 前端开发 数据处理
Vue导出el-table表格为Excel文件的两种方式
Vue导出el-table表格为Excel文件的两种方式
74 6
|
2月前
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。