poi导出excel大数据_poi实现excel导出 导出数据类型为list<map> - CSDN
  • excel导出,如果数据量在百万级,会出现俩点内存溢出的问题: 1. 查询数据量过大,导致内存溢出。 该问题可以通过分批查询来解决; 2. 最后下载的时候大EXCEL转换的输出流内存溢出;该方式可以通过新版的...

    一. 简介

              excel导出,如果数据量在百万级,会出现俩点内存溢出的问题:

              1. 查询数据量过大,导致内存溢出。 该问题可以通过分批查询来解决;

              2. 最后下载的时候大EXCEL转换的输出流内存溢出;该方式可以通过新版的SXSSFWorkbook来解决,可通过其构造函数执指定在内存中缓存的行数,剩余的会自动缓存在硬盘的临时目录上,同时,并不会存在页面卡顿的情况;

              3. 为了能够使用不同的mapper并分批写数据, 采用了外观模式和模板方法模式,大体分三步:

                  a. 根据总数量生成excel,确定sheet的数量和写标题;

                  b. 写数据,在可变的匿名内部类中实现写入逻辑;
                  c. 转换输出流进行下载;

              4. 使用案例在3.3 ServiceImpl中,可自行书写。

              5. 最近太忙,写的太仓促,性能我感觉还有一倍的优化空间,比如循环次数,现在存在无意义空循环(这个耗时比较多)的情况,缓冲流,mybatis的浮标等,待优化........   

              6. 优化空间很大  刚试了下 把空循环去掉  4个字段 90W条数据  40s  180W  75s  300W 122s

              7. 转战阿里开源的EasyExcel了, 那个内存控制在kb级别,绝对不会内存溢出。使用说明请参见博主的另一篇文章:

    阿里开源(EasyExcel)---导出EXCEL

              8. 导入的也有,请参见另一篇文章: 阿里开源(EasyExcel)---导入EXCEL

    二. 工具代码

    2.1 配置

    2.1.1 pom.xml

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

    注: 如果是springboot2.0,则不需要poi依赖,如果是1.0,则需要poi依赖,并且poi和poi-ooxml的版本要保持一致。

              别的依赖我就不加了。

    2.1.2 application.yml

    # pagehelper
    pagehelper:
        helperDialect: mysql
        reasonable: false # 如果没有数据  返回空 而非最后一页的数据
        supportMethodsArguments: true
        params: count=countSql
        returnPageInfo: check

    注:  reasonable一定要为false, 其他的我就不粘了。

    2.2 ExcelConstant

    package com.yzx.caasscs.constant;
    
    /**
     * @author qjwyss
     * @date 2018/9/19
     * @description EXCEL常量类
     */
    public class ExcelConstant {
    
        /**
         * 每个sheet存储的记录数 100W
         */
        public static final Integer PER_SHEET_ROW_COUNT = 1000000;
    
        /**
         * 每次向EXCEL写入的记录数(查询每页数据大小) 20W
         */
        public static final Integer PER_WRITE_ROW_COUNT = 200000;
    
    
        /**
         * 每个sheet的写入次数 5
         */
        public static final Integer PER_SHEET_WRITE_COUNT = PER_SHEET_ROW_COUNT / PER_WRITE_ROW_COUNT;
    
    
    }
    

    注: xlsx模式的excel每个sheet最多存储104W,此处我就每个sheet存储了 100W数据;每次查询20W数据; 自己根据内存来调合适的大小,写入次数待优化。

    2.3 写数据委托类

    package com.yzx.caasscs.util;
    
    import org.apache.poi.xssf.streaming.SXSSFSheet;
    
    /**
     * @author qjwyss
     * @date 2018/9/20
     * @description EXCEL写数据委托类
     */
    public interface WriteExcelDataDelegated {
    
        /**
         * EXCEL写数据委托类  针对不同的情况自行实现
         *
         * @param eachSheet     指定SHEET
         * @param startRowCount 开始行
         * @param endRowCount   结束行
         * @param currentPage   分批查询开始页
         * @param pageSize      分批查询数据量
         * @throws Exception
         */
        public abstract void writeExcelData(SXSSFSheet eachSheet, Integer startRowCount, Integer endRowCount, Integer currentPage, Integer pageSize) throws Exception;
    
    
    }
    

    2.4 DateUtil工具类(非必须)

    package com.yzx.caasscs.util;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * @author qjwyss
     * @date 2018/9/20
     * @description 日期工具类
     */
    public class DateUtil {
    
        public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    
    
        /**
         * 将日期转换为字符串
         *
         * @param date   DATE日期
         * @param format 转换格式
         * @return 字符串日期
         */
        public static String formatDate(Date date, String format) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
            return simpleDateFormat.format(date);
        }
    
    
    }
    

    2.5 POI工具类

    package com.yzx.caasscs.util;
    
    
    import com.yzx.caasscs.constant.ExcelConstant;
    import org.apache.poi.xssf.streaming.SXSSFCell;
    import org.apache.poi.xssf.streaming.SXSSFRow;
    import org.apache.poi.xssf.streaming.SXSSFSheet;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.servlet.http.HttpServletResponse;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Date;
    
    /**
     * @author qjwyss
     * @date 2018/9/18
     * @description POI导出工具类
     */
    public class PoiUtil {
    
        private final static Logger logger = LoggerFactory.getLogger(PoiUtil.class);
    
        /**
         * 初始化EXCEL(sheet个数和标题)
         *
         * @param totalRowCount 总记录数
         * @param titles        标题集合
         * @return XSSFWorkbook对象
         */
        public static SXSSFWorkbook initExcel(Integer totalRowCount, String[] titles) {
    
            // 在内存当中保持 100 行 , 超过的数据放到硬盘中在内存当中保持 100 行 , 超过的数据放到硬盘中
            SXSSFWorkbook wb = new SXSSFWorkbook(100);
    
            Integer sheetCount = ((totalRowCount % ExcelConstant.PER_SHEET_ROW_COUNT == 0) ?
                    (totalRowCount / ExcelConstant.PER_SHEET_ROW_COUNT) : (totalRowCount / ExcelConstant.PER_SHEET_ROW_COUNT + 1));
    
            // 根据总记录数创建sheet并分配标题
            for (int i = 0; i < sheetCount; i++) {
                SXSSFSheet sheet = wb.createSheet("sheet" + (i + 1));
                SXSSFRow headRow = sheet.createRow(0);
    
                for (int j = 0; j < titles.length; j++) {
                    SXSSFCell headRowCell = headRow.createCell(j);
                    headRowCell.setCellValue(titles[j]);
                }
            }
    
            return wb;
        }
    
    
        /**
         * 下载EXCEL到本地指定的文件夹
         *
         * @param wb         EXCEL对象SXSSFWorkbook
         * @param exportPath 导出路径
         */
        public static void downLoadExcelToLocalPath(SXSSFWorkbook wb, String exportPath) {
            FileOutputStream fops = null;
            try {
                fops = new FileOutputStream(exportPath);
                wb.write(fops);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (null != wb) {
                    try {
                        wb.dispose();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (null != fops) {
                    try {
                        fops.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    
        /**
         * 下载EXCEL到浏览器
         *
         * @param wb       EXCEL对象XSSFWorkbook
         * @param response
         * @param fileName 文件名称
         * @throws IOException
         */
        public static void downLoadExcelToWebsite(SXSSFWorkbook wb, HttpServletResponse response, String fileName) throws IOException {
    
            response.setHeader("Content-disposition", "attachment; filename="
                    + new String((fileName + ".xlsx").getBytes("utf-8"), "ISO8859-1"));//设置下载的文件名
    
            OutputStream outputStream = null;
            try {
                outputStream = response.getOutputStream();
                wb.write(outputStream);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (null != wb) {
                    try {
                        wb.dispose();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (null != outputStream) {
                    try {
                        outputStream.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    
        /**
         * 导出Excel到本地指定路径
         *
         * @param totalRowCount           总记录数
         * @param titles                  标题
         * @param exportPath              导出路径
         * @param writeExcelDataDelegated 向EXCEL写数据/处理格式的委托类 自行实现
         * @throws Exception
         */
        public static final void exportExcelToLocalPath(Integer totalRowCount, String[] titles, String exportPath, WriteExcelDataDelegated writeExcelDataDelegated) throws Exception {
    
            logger.info("开始导出:" + DateUtil.formatDate(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
    
            // 初始化EXCEL
            SXSSFWorkbook wb = PoiUtil.initExcel(totalRowCount, titles);
    
            // 调用委托类分批写数据
            int sheetCount = wb.getNumberOfSheets();
            for (int i = 0; i < sheetCount; i++) {
                SXSSFSheet eachSheet = wb.getSheetAt(i);
    
                for (int j = 1; j <= ExcelConstant.PER_SHEET_WRITE_COUNT; j++) {
    
                    int currentPage = i * ExcelConstant.PER_SHEET_WRITE_COUNT + j;
                    int pageSize = ExcelConstant.PER_WRITE_ROW_COUNT;
                    int startRowCount = (j - 1) * ExcelConstant.PER_WRITE_ROW_COUNT + 1;
                    int endRowCount = startRowCount + pageSize - 1;
    
    
                    writeExcelDataDelegated.writeExcelData(eachSheet, startRowCount, endRowCount, currentPage, pageSize);
    
                }
            }
    
    
            // 下载EXCEL
            PoiUtil.downLoadExcelToLocalPath(wb, exportPath);
    
            logger.info("导出完成:" + DateUtil.formatDate(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
        }
    
    
        /**
         * 导出Excel到浏览器
         *
         * @param response
         * @param totalRowCount           总记录数
         * @param fileName                文件名称
         * @param titles                  标题
         * @param writeExcelDataDelegated 向EXCEL写数据/处理格式的委托类 自行实现
         * @throws Exception
         */
        public static final void exportExcelToWebsite(HttpServletResponse response, Integer totalRowCount, String fileName, String[] titles, WriteExcelDataDelegated writeExcelDataDelegated) throws Exception {
    
            logger.info("开始导出:" + DateUtil.formatDate(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
    
            // 初始化EXCEL
            SXSSFWorkbook wb = PoiUtil.initExcel(totalRowCount, titles);
    
    
            // 调用委托类分批写数据
            int sheetCount = wb.getNumberOfSheets();
            for (int i = 0; i < sheetCount; i++) {
                SXSSFSheet eachSheet = wb.getSheetAt(i);
    
                for (int j = 1; j <= ExcelConstant.PER_SHEET_WRITE_COUNT; j++) {
    
                    int currentPage = i * ExcelConstant.PER_SHEET_WRITE_COUNT + j;
                    int pageSize = ExcelConstant.PER_WRITE_ROW_COUNT;
                    int startRowCount = (j - 1) * ExcelConstant.PER_WRITE_ROW_COUNT + 1;
                    int endRowCount = startRowCount + pageSize - 1;
    
                    writeExcelDataDelegated.writeExcelData(eachSheet, startRowCount, endRowCount, currentPage, pageSize);
    
                }
            }
    
    
            // 下载EXCEL
            PoiUtil.downLoadExcelToWebsite(wb, response, fileName);
    
            logger.info("导出完成:" + DateUtil.formatDate(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
        }
    
    
    }
    

    三. 使用DEMO

    3.1 Controller

    package com.yzx.caasscs.controller.organiza;
    
    import com.yzx.caasscs.controller.BaseController;
    import com.yzx.caasscs.service.organiza.UserService;
    import com.yzx.caasscs.vo.PageVO;
    import com.yzx.caasscs.vo.ResultVO;
    import com.yzx.caasscs.vo.organiza.UserVO;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiImplicitParam;
    import io.swagger.annotations.ApiImplicitParams;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    import springfox.documentation.annotations.ApiIgnore;
    
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @author qjwyss
     * @date 2018/8/30
     * @description 用户控制类
     */
    @Api(tags = {"UserController"}, description = "用户Controller")
    @RestController
    @RequestMapping(value = "/user")
    public class UserController extends BaseController {
    
        @Autowired
        private UserService userService;
    
    
        @ApiOperation("导出用户EXCEL")
        @ApiImplicitParams({
                @ApiImplicitParam(paramType = "query", dataType = "Long", name = "loginUid", value = "登录用户UID", required = true),
                @ApiImplicitParam(paramType = "query", dataType = "Long", name = "uid", value = "用户UID", required = true)
        })
        @GetMapping("/export")
        public ResultVO<Void> exportUser(@ApiIgnore UserVO userVO, HttpServletResponse response) throws Exception {
            return this.userService.export(userVO, response);
        }
    
    }
    

    3.2 Service

    package com.yzx.caasscs.service.organiza;
    
    import com.yzx.caasscs.vo.PageVO;
    import com.yzx.caasscs.vo.ResultVO;
    import com.yzx.caasscs.vo.organiza.UserVO;
    
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @author qjwyss
     * @date 2018/8/30
     * @description 用户SERVICE
     */
    public interface UserService {
    
    
        /**
         * 导出用户EXCEL
         *
         * @param userVO
         * @return VOID
         * @throws Exception
         */
        ResultVO<Void> export(UserVO userVO, HttpServletResponse response) throws Exception;
    
    
    }
    

    3.3 ServiceImpl

    package com.yzx.caasscs.service.impl.organiza;
    
    import com.github.pagehelper.PageHelper;
    import com.github.pagehelper.PageInfo;
    import com.yzx.caasscs.constant.middleware.RedisConstant;
    import com.yzx.caasscs.constant.organiza.UserApartmentConstant;
    import com.yzx.caasscs.constant.organiza.UserConstant;
    import com.yzx.caasscs.constant.organiza.UserRoleConstant;
    import com.yzx.caasscs.constant.sys.SysLogConstant;
    import com.yzx.caasscs.entity.dscaasscs.organiza.User;
    import com.yzx.caasscs.entity.dscaasscs.organiza.UserApartment;
    import com.yzx.caasscs.entity.dscaasscs.organiza.UserRole;
    import com.yzx.caasscs.mapper.dscaasscs.organiza.UserApartmentMapper;
    import com.yzx.caasscs.mapper.dscaasscs.organiza.UserMapper;
    import com.yzx.caasscs.mapper.dscaasscs.organiza.UserRoleMapper;
    import com.yzx.caasscs.mapper.dscaasscs.sys.RoleMenuMapper;
    import com.yzx.caasscs.service.organiza.UserService;
    import com.yzx.caasscs.service.sys.SysLogService;
    import com.yzx.caasscs.util.CommonUtil;
    import com.yzx.caasscs.util.DateUtil;
    import com.yzx.caasscs.util.PoiUtil;
    import com.yzx.caasscs.util.WriteExcelDataDelegated;
    import com.yzx.caasscs.vo.PageVO;
    import com.yzx.caasscs.vo.ResultVO;
    import com.yzx.caasscs.vo.organiza.UserApartmentVO;
    import com.yzx.caasscs.vo.organiza.UserRoleVO;
    import com.yzx.caasscs.vo.organiza.UserVO;
    import com.yzx.caasscs.vo.sys.MenuVO;
    import com.yzx.caasscs.vo.sys.RoleMenuVO;
    import com.yzx.caasscs.vo.sys.SysLogVO;
    import net.sf.json.JSONObject;
    import org.apache.poi.xssf.streaming.SXSSFRow;
    import org.apache.poi.xssf.streaming.SXSSFSheet;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.util.CollectionUtils;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    /**
     * @author qjwyss
     * @date 2018/8/30
     * @description 用户SERVICEIMPL
     */
    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserMapper userMapper;
    
        @Autowired
        private HttpServletRequest request;
    
    
        @Override
        public ResultVO<Void> export(UserVO userVO, HttpServletResponse response) throws Exception {
    
            // 总记录数
            Integer totalRowCount = this.userMapper.selectUserVOCount(userVO);
    
            // 导出EXCEL文件名称
            String filaName = "用户EXCEL";
    
            // 标题
            String[] titles = {"账号", "密码", "状态", "昵称", "职位", "手机号", "邮箱", "创建人ID", "创建时间", "修改人ID", "修改时间"};
    
            // 开始导入
            PoiUtil.exportExcelToWebsite(response, totalRowCount, filaName, titles, new WriteExcelDataDelegated() {
                @Override
                public void writeExcelData(SXSSFSheet eachSheet, Integer startRowCount, Integer endRowCount, Integer currentPage, Integer pageSize) throws Exception {
    
                    PageHelper.startPage(currentPage, pageSize);
                    List<UserVO> userVOList = userMapper.selectUserVOList(userVO);
    
                    if (!CollectionUtils.isEmpty(userVOList)) {
    
                        // --------------   这一块变量照着抄就行  强迫症 后期也封装起来     ----------------------
                        for (int i = startRowCount; i <= endRowCount; i++) {
                            SXSSFRow eachDataRow = eachSheet.createRow(i);
                            if ((i - startRowCount) < userVOList.size()) {
    
                                UserVO eachUserVO = userVOList.get(i - startRowCount);
                                // ---------   这一块变量照着抄就行  强迫症 后期也封装起来     -----------------------
    
                                eachDataRow.createCell(0).setCellValue(eachUserVO.getUsername() == null ? "" : eachUserVO.getUsername());
                                eachDataRow.createCell(1).setCellValue(eachUserVO.getPassword() == null ? "" : eachUserVO.getPassword());
                                eachDataRow.createCell(2).setCellValue(eachUserVO.getUserState() == null ? "" : (eachUserVO.getUserState() == 1 ? "启用" : "停用"));
                                eachDataRow.createCell(3).setCellValue(eachUserVO.getNickname() == null ? "" : eachUserVO.getNickname());
                                eachDataRow.createCell(4).setCellValue(eachUserVO.getPosition() == null ? "" : eachUserVO.getPosition());
                                eachDataRow.createCell(5).setCellValue(eachUserVO.getMobile() == null ? "" : eachUserVO.getMobile());
                                eachDataRow.createCell(6).setCellValue(eachUserVO.getEmail() == null ? "" : eachUserVO.getEmail());
                                if (null != eachUserVO.getCreateUid()) {
                                    eachDataRow.createCell(7).setCellValue(eachUserVO.getCreateUid());
                                }
                                if (null != eachUserVO.getCreateTime()) {
                                    eachDataRow.createCell(8).setCellValue(DateUtil.formatDate(eachUserVO.getCreateTime(), DateUtil.YYYY_MM_DD_HH_MM_SS));
                                }
                                if (null != eachUserVO.getUpdateUid()) {
                                    eachDataRow.createCell(9).setCellValue(eachUserVO.getUpdateUid());
                                }
                                if (null != eachUserVO.getUpdateTime()) {
                                    eachDataRow.createCell(10).setCellValue(DateUtil.formatDate(eachUserVO.getUpdateTime(), DateUtil.YYYY_MM_DD_HH_MM_SS));
                                }
                            }
                        }
                    }
    
                }
            });
    
            return ResultVO.getSuccess("导出用户EXCEL成功");
        }
    
    
    }
    

    3.4 mapper

    package com.yzx.caasscs.mapper.dscaasscs.organiza;
    
    import com.yzx.caasscs.entity.dscaasscs.organiza.User;
    import com.yzx.caasscs.vo.organiza.UserVO;
    
    import java.util.List;
    
    /**
     * @author qjwyss
     * @date 2018/8/29
     * @description 用户MAPPER
     */
    public interface UserMapper {
    
    
        /**
         * 查询用户列表
         *
         * @param userVO
         * @return UserVO集合
         * @throws Exception
         */
        List<UserVO> selectUserVOList(UserVO userVO) throws Exception;
    
    
        /**
         * 查询用户数量
         *
         * @param userVO
         * @return 用户数量
         * @throws Exception
         */
        Integer selectUserVOCount(UserVO userVO) throws Exception;
    
    }

    3.5 mapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.yzx.caasscs.mapper.dscaasscs.organiza.UserMapper" >
    
      <resultMap id="BaseResultMap" type="com.yzx.caasscs.entity.dscaasscs.organiza.User" >
        <id column="uid" property="uid" jdbcType="BIGINT" />
        <result column="username" property="username" jdbcType="VARCHAR" />
        <result column="password" property="password" jdbcType="VARCHAR" />
        <result column="state" property="state" jdbcType="INTEGER" />
        <result column="nickname" property="nickname" jdbcType="VARCHAR" />
        <result column="position" property="position" jdbcType="VARCHAR" />
        <result column="mobile" property="mobile" jdbcType="VARCHAR" />
        <result column="email" property="email" jdbcType="VARCHAR" />
        <result column="create_uid" property="createUid" jdbcType="BIGINT" />
        <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
        <result column="update_uid" property="updateUid" jdbcType="BIGINT" />
        <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
      </resultMap>
    
    
      <!-- 查询用户分页列表返回MAP -->
      <resultMap id="SelectUserVOListMap" type="com.yzx.caasscs.vo.organiza.UserVO">
        <id column="uid" property="uid" jdbcType="BIGINT" />
        <result column="username" property="username" jdbcType="VARCHAR" />
        <result column="user_state" property="userState" jdbcType="INTEGER" />
        <result column="nickname" property="nickname" jdbcType="VARCHAR" />
        <result column="position" property="position" jdbcType="VARCHAR" />
        <result column="mobile" property="mobile" jdbcType="VARCHAR" />
        <result column="email" property="email" jdbcType="VARCHAR" />
        <result column="create_uid" property="createUid" jdbcType="BIGINT" />
        <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
        <result column="update_uid" property="updateUid" jdbcType="BIGINT" />
        <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
        <result column="apartment_name" property="apartmentName" jdbcType="VARCHAR" />
        <result column="role_names" property="roleNames" jdbcType="VARCHAR" />
      </resultMap>
    
    
      <sql id="Base_Column_List" >
        uid, username, password, state, nickname, position, mobile, email, create_uid, create_time,
        update_uid, update_time
      </sql>
    
    
      <!-- 查询用户列表 -->
      <select id="selectUserVOList" parameterType="com.yzx.caasscs.vo.organiza.UserVO" resultMap="SelectUserVOListMap">
        SELECT
    		U.uid, U.username, U.state AS user_state, U.nickname, U.position, U.mobile, U.email, U.create_uid, U.create_time,
    		U.update_uid, U.update_time,
    		A.apartment_name,
    		(
    			SELECT
    				GROUP_CONCAT( R.role_name ) AS role_name_list
    			FROM
    				user_role AS UR
    				LEFT JOIN role AS R ON R.rid = UR.rid
    			WHERE
    				UR.state > 0
    				AND UR.uid = U.uid
    			GROUP BY UR.uid
    		) role_names
        FROM
            `user` AS U
            LEFT JOIN user_apartment AS UA ON UA.uid = U.uid
            LEFT JOIN apartment AS A ON A.aid = UA.aid
        WHERE
            U.state > 0
            <if test="userState != null">
              AND U.state = #{userState,jdbcType=INTEGER}
            </if>
            <if test="nickname != null and nickname != ''">
              AND U.nickname LIKE CONCAT("%", #{nickname,jdbcType=VARCHAR}, "%")
            </if>
            <if test="apartmentName != null and apartmentName != ''">
              AND A.apartment_name LIKE CONCAT("%", #{apartmentName,jdbcType=VARCHAR}, "%")
            </if>
        ORDER BY U.create_time DESC
    
      </select>
    
    
      <!-- 查询用户列表数量 -->
      <select id="selectUserVOCount" parameterType="com.yzx.caasscs.vo.organiza.UserVO" resultType="java.lang.Integer" >
        SELECT
            COUNT(1)
        FROM
            `user` AS U
            LEFT JOIN user_apartment AS UA ON UA.uid = U.uid
            LEFT JOIN apartment AS A ON A.aid = UA.aid
        WHERE
            U.state > 0
            <if test="userState != null">
              AND U.state = #{userState,jdbcType=INTEGER}
            </if>
            <if test="nickname != null and nickname != ''">
              AND U.nickname LIKE CONCAT("%", #{nickname,jdbcType=VARCHAR}, "%")
            </if>
            <if test="apartmentName != null and apartmentName != ''">
              AND A.apartment_name LIKE CONCAT("%", #{apartmentName,jdbcType=VARCHAR}, "%")
            </if>
      </select>
      
    
    </mapper>

    4. 测试

    每个sheet存100W,每次查询写20W,每条记录10个字段,时间如下:

    数据量 时间
    100W 3.5分钟
    150W 7分钟

     

     

    展开全文
  • Excel中的数据量超过10万行时,在用POI读取文件流时很容易引起失败,需要引入xlsx-streamer来进行资源的打开,剩下的处理同POI处理上百行数据量类似:filePath=>FileInputStream=>Workbook=>Sheet=>...

      1. 大数据量的导入

    当Excel中的数据量超过10万行时,在用POI读取文件流时很容易引起失败,需要引入xlsx-streamer来进行资源的打开,剩下的处理同POI处理上百行数据量类似:filePath=>FileInputStream=>Workbook=>Sheet=>Row=>Cell=>Java反射获取值。

     <dependency>
           <groupId>com.monitorjbl</groupId>
           <artifactId>xlsx-streamer</artifactId>
           <version>1.2.1</version>
    </dependency>  

    使用StreamingReader来进行对Workbook的获取。需要注意主要针对超过10万行要解析的Excel的Workbook获取,缓存到内存中的行数默认是10行,读取资源时缓存到内存的字节大小默认是1024,资源必须打开,File或者InputStream都可以,但是只能打开XLSX格式的文件。
    public static Workbook obtainWorkbookByStream(String filePath) throws Exception {
          // StreamingReader用于读取Excel的内容,不能写入,不能随机读取Excel的内容
          FileInputStream in = new FileInputStream(filePath);
          Workbook workbook = StreamingReader.builder().rowCacheSize(100).bufferSize(4096).open(in);
          return workbook;
    }

    2. 大数据量的导出

    对于大数据量的导出通常采用分而治之的思想,将大数据量分批次的导出到多个Excel文件或者单个Excel文件的多个sheet,也可导出到多个Excel文件后合并从单独的文件,其实现方式可参考:https://github.com/chunericli/xpt-excel-extension

    总结:大数据量的处理需要注意对内存使用的影响和对业务的影响。除非必要,要不然最好使用异步的方式进行处理,即首先保存文件元数据信息,然后分批次保存数据和分批次读取数据。

    展开全文
  • Java实现导出excel表格功能,大部分都会使用apache poi,apache poi API 地址 POI之前的版本不支持大数据量处理,如果数据过多则经常报OOM错误,有时候调整JVM大小效果也不是太好。3.8版本的POI新出来了...

    Java实现导出excel表格功能,大部分都会使用apache poi,apache poi API 地址 
    POI之前的版本不支持大数据量处理,如果数据过多则经常报OOM错误,有时候调整JVM大小效果也不是太好。3.8版本的POI新出来了SXSSFWorkbook,可以支持大数据量的操作,只是SXSSFWorkbook只支持.xlsx格式,不支持.xls格式。 
    3.8版本的POI对excel的导出操作,一般只使用HSSFWorkbook以及SXSSFWorkbook,HSSFWorkbook用来处理较少的数据量,SXSSFWorkbook用来处理大数据量以及超大数据量的导出。 
    代码: 
    git地址 有3.9jar包

    package qs.test;
     
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
     
    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.util.CellReference;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
     
    /**
     * ClassName: SXSSFTest
     * @Description: TODO
     * @author qiaoshuai
     */
    public class SXSSFTest {
     
        public static void main(String[] args) throws IOException {
            // 创建基于stream的工作薄对象的
            SXSSFWorkbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory,
                                                        // exceeding rows will be
                                                        // flushed to disk
            // SXSSFWorkbook wb = new SXSSFWorkbook();
            // wb.setCompressTempFiles(true); // temp files will be gzipped
            Sheet sh = wb.createSheet();
            // 使用createRow将信息写在内存中。
            for (int rownum = 0; rownum < 1000; rownum++) {
                Row row = sh.createRow(rownum);
                for (int cellnum = 0; cellnum < 10; cellnum++) {
                    Cell cell = row.createCell(cellnum);
                    String address = new CellReference(cell).formatAsString();
                    cell.setCellValue(address);
                }
     
            }
     
            // Rows with rownum < 900 are flushed and not accessible
            // 当使用getRow方法访问的时候,将内存中的信息刷新到硬盘中去。
            for (int rownum = 0; rownum < 900; rownum++) {
                System.out.println(sh.getRow(rownum));
            }
     
            // ther last 100 rows are still in memory
            for (int rownum = 900; rownum < 1000; rownum++) {
                System.out.println(sh.getRow(rownum));
            }
            // 写入文件中
            FileOutputStream out = new FileOutputStream("G://sxssf.xlsx");
            wb.write(out);
            // 关闭文件流对象
            out.close();
            System.out.println("基于流写入执行完毕!");
        }
     
    }

    SXSSFWorkbook workbook = new SXSSFWorkbook(100);

     

    private void setSheetFinishStyle(Sheet sheet, int colSize)
    {
        for (int i = 0; i < colSize; i++)
        {
            if ((sheet instanceof SXSSFSheet)) {
                ((SXSSFSheet)sheet).trackAllColumnsForAutoSizing();
            }
            sheet.autoSizeColumn((short)i);
        }
    
        sheet.createFreezePane(0, 1, 0, 1);
    }
    展开全文
  • POI导出大数据量excel(注:项目源码及后续更新请点击)1、ExcelUtils类:package Utils; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.apache.poi.common....

    POI导出大数据量excel

    注:项目源码及后续更新请点击

    1、ExcelUtils类:

    package Utils;
    
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import org.apache.poi.common.usermodel.Hyperlink;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFFont;
    import org.apache.poi.hssf.util.HSSFColor;
    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.CreationHelper;
    import org.apache.poi.ss.usermodel.Font;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.streaming.SXSSFCell;
    import org.apache.poi.xssf.streaming.SXSSFRow;
    import org.apache.poi.xssf.streaming.SXSSFSheet;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    import org.apache.poi.xssf.usermodel.XSSFHyperlink;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.math.BigDecimal;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     * Created by Cheung on 2017/12/19.
     *
     * Apache POI操作Excel对象
     * HSSF:操作Excel 2007之前版本(.xls)格式,生成的EXCEL不经过压缩直接导出
     * XSSF:操作Excel 2007及之后版本(.xlsx)格式,内存占用高于HSSF
     * SXSSF:从POI3.8 beta3开始支持,基于XSSF,低内存占用,专门处理大数据量(建议)。
     *
     * 注意:
     * 		值得注意的是SXSSFWorkbook只能写(导出)不能读(导入)
     *
     * 说明:
     * 		.xls格式的excel(最大行数65536行,最大列数256列)
     * 	   	.xlsx格式的excel(最大行数1048576行,最大列数16384列)
     */
    public class ExcelUtil {
    
    	public static final String DEFAULT_DATE_PATTERN = "yyyy年MM月dd日";// 默认日期格式
    	public static final int DEFAULT_COLUMN_WIDTH = 17;// 默认列宽
    
    
    	/**
    	 * 导出Excel(.xlsx)格式
    	 * @param titleList 表格头信息集合
    	 * @param dataArray 数据数组
    	 * @param os 文件输出流
    	 */
    	public static void exportExcel(ArrayList<LinkedHashMap> titleList, JSONArray dataArray, OutputStream os) {
    		String datePattern = DEFAULT_DATE_PATTERN;
    		int minBytes = DEFAULT_COLUMN_WIDTH;
    
    		/**
    		 * 声明一个工作薄
     		 */
    		SXSSFWorkbook workbook = new SXSSFWorkbook(1000);// 大于1000行时会把之前的行写入硬盘
    		workbook.setCompressTempFiles(true);
    
    		// 表头1样式
    		CellStyle title1Style = workbook.createCellStyle();
    		title1Style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 水平居中
    		title1Style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
    		Font titleFont = workbook.createFont();// 字体
    		titleFont.setFontHeightInPoints((short) 20);
    		titleFont.setBoldweight((short) 700);
    		title1Style.setFont(titleFont);
    
    		// 表头2样式
    		CellStyle title2Style = workbook.createCellStyle();
    		title2Style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    		title2Style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
    		title2Style.setBorderTop(HSSFCellStyle.BORDER_THIN);// 上边框
    		title2Style.setBorderRight(HSSFCellStyle.BORDER_THIN);// 右
    		title2Style.setBorderBottom(HSSFCellStyle.BORDER_THIN);// 下
    		title2Style.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 左
    		Font title2Font = workbook.createFont();
    		title2Font.setUnderline((byte) 1);
    		title2Font.setColor(HSSFColor.BLUE.index);
    		title2Style.setFont(title2Font);
    
    		// head样式
    		CellStyle headerStyle = workbook.createCellStyle();
    		headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    		headerStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
    		headerStyle.setFillForegroundColor(HSSFColor.LIGHT_GREEN.index);// 设置颜色
    		headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);// 前景色纯色填充
    		headerStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
    		headerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
    		headerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    		headerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    		Font headerFont = workbook.createFont();
    		headerFont.setFontHeightInPoints((short) 12);
    		headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    		headerStyle.setFont(headerFont);
    
    		// 单元格样式
    		CellStyle cellStyle = workbook.createCellStyle();
    		cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    		cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
    		cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
    		cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
    		cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    		cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    		Font cellFont = workbook.createFont();
    		cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
    		cellStyle.setFont(cellFont);
    
    
    		String title1 = (String) titleList.get(0).get("title1");
    		String title2 = (String) titleList.get(0).get("title2");
    		LinkedHashMap<String, String> headMap = titleList.get(1);
    
    		/**
    		 * 生成一个(带名称)表格
    		 */
    		SXSSFSheet sheet = (SXSSFSheet) workbook.createSheet(title1);
    		sheet.createFreezePane(0, 3, 0, 3);// (单独)冻结前三行
    
    		/**
    		 * 生成head相关信息+设置每列宽度
    		 */
    		int[] colWidthArr = new int[headMap.size()];// 列宽数组
    		String[] headKeyArr = new String[headMap.size()];// headKey数组
    		String[] headValArr = new String[headMap.size()];// headVal数组
    		int i = 0;
    		for (Map.Entry<String, String> entry : headMap.entrySet()) {
    			headKeyArr[i] = entry.getKey();
    			headValArr[i] = entry.getValue();
    
    			int bytes = headKeyArr[i].getBytes().length;
    			colWidthArr[i] = bytes < minBytes ? minBytes : bytes;
    			sheet.setColumnWidth(i, colWidthArr[i] * 256);// 设置列宽
    			i++;
    		}
    
    
    		/**
    		 * 遍历数据集合,产生Excel行数据
     		 */
    		int rowIndex = 0;
    		for (Object obj : dataArray) {
    			// 生成title+head信息
    			if (rowIndex == 0) {
    				SXSSFRow title1Row = (SXSSFRow) sheet.createRow(0);// title1行
    				title1Row.createCell(0).setCellValue(title1);
    				title1Row.getCell(0).setCellStyle(title1Style);
    				sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headMap.size() - 1));// 合并单元格
    
    				SXSSFRow title2Row = (SXSSFRow) sheet.createRow(1);// title2行
    				title2Row.createCell(0).setCellValue(title2);
    
    				CreationHelper createHelper = workbook.getCreationHelper();
    				XSSFHyperlink  hyperLink = (XSSFHyperlink) createHelper.createHyperlink(Hyperlink.LINK_URL);
    				hyperLink.setAddress(title2);
    				title2Row.getCell(0).setHyperlink(hyperLink);// 添加超链接
    
    				title2Row.getCell(0).setCellStyle(title2Style);
    				sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, headMap.size() - 1));// 合并单元格
    
    				SXSSFRow headerRow = (SXSSFRow) sheet.createRow(2);// head行
    				for (int j = 0; j < headValArr.length; j++) {
    					headerRow.createCell(j).setCellValue(headValArr[j]);
    					headerRow.getCell(j).setCellStyle(headerStyle);
    				}
    				rowIndex = 3;
    			}
    
    			JSONObject jo = (JSONObject) JSONObject.toJSON(obj);
    			// 生成数据
    			SXSSFRow dataRow = (SXSSFRow) sheet.createRow(rowIndex);// 创建行
    			for (int k = 0; k < headKeyArr.length; k++) {
    				SXSSFCell cell = (SXSSFCell) dataRow.createCell(k);// 创建单元格
    				Object o = jo.get(headKeyArr[k]);
    				String cellValue = "";
    
    				if (o == null) {
    					cellValue = "";
    				} else if (o instanceof Date) {
    					cellValue = new SimpleDateFormat(datePattern).format(o);
    				} else if (o instanceof Float || o instanceof Double) {
    					cellValue = new BigDecimal(o.toString()).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    				} else {
    					cellValue = o.toString();
    				}
    
    				if (cellValue.equals("true")) {
    					cellValue = "男";
    				} else if (cellValue.equals("false")) {
    					cellValue = "女";
    				}
    
    				cell.setCellValue(cellValue);
    				cell.setCellStyle(cellStyle);
    			}
    			rowIndex++;
    		}
    
    		try {
    			workbook.write(os);
    			os.flush();// 刷新此输出流并强制将所有缓冲的输出字节写出
    			os.close();// 关闭流
    			workbook.dispose();// 释放workbook所占用的所有windows资源
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    
    }
    


    2、Student类:

    package domain;
    
    import java.util.Date;
    
    /**
     * Created by Cheung on 2017/12/19.
     */
    public class Student {
    
    	private String name;
    	private int age;
    	private Date birthday;
    	private float height;
    	private double weight;
    	private boolean sex;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	public Date getBirthday() {
    		return birthday;
    	}
    
    	public void setBirthday(Date birthday) {
    		this.birthday = birthday;
    	}
    
    	public float getHeight() {
    		return height;
    	}
    
    	public void setHeight(float height) {
    		this.height = height;
    	}
    
    	public double getWeight() {
    		return weight;
    	}
    
    	public void setWeight(double weight) {
    		this.weight = weight;
    	}
    
    	public boolean isSex() {
    		return sex;
    	}
    
    	public void setSex(boolean sex) {
    		this.sex = sex;
    	}
    }
    

    3、ExcelExportTest类:

    package controller;
    
    import Utils.ExcelUtil;
    import com.alibaba.fastjson.JSONArray;
    import domain.Student;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.LinkedHashMap;
    
    /**
     * Created by Cheung on 2017/12/19.
     */
    public class ExcelExportTest {
    
    	public static void main(String[] args) throws IOException {
    		// 模拟10W条数据
    		int count = 100000;
    	 	JSONArray studentArray = new JSONArray();
    		for (int i = 0; i < count; i++) {
    			Student s = new Student();
    			s.setName("POI" + i);
    			s.setAge(i);
    			s.setBirthday(new Date());
    			s.setHeight(i);
    			s.setWeight(i);
    			s.setSex(i % 2 == 0 ? false : true);
    			studentArray.add(s);
    		}
    
    		ArrayList<LinkedHashMap> titleList = new ArrayList<LinkedHashMap>();
    		LinkedHashMap<String, String> titleMap = new LinkedHashMap<String, String>();
    		titleMap.put("title1","POI导出大数据量Excel Demo");
    		titleMap.put("title2","https://github.com/550690513");
    		LinkedHashMap<String, String> headMap = new LinkedHashMap<String, String>();
    		headMap.put("name", "姓名");
    		headMap.put("age", "年龄");
    		headMap.put("birthday", "生日");
    		headMap.put("height", "身高");
    		headMap.put("weight", "体重");
    		headMap.put("sex", "性别");
    		titleList.add(titleMap);
    		titleList.add(headMap);
    
    
    
    		File file = new File("D://ExcelExportDemo/");
    		if (!file.exists()) file.mkdir();// 创建该文件夹目录
    		OutputStream os = null;
    		Date date = new Date();
    		try {
    			// .xlsx格式
    			os = new FileOutputStream(file.getAbsolutePath() + "/" + date.getTime() + ".xlsx");
    			System.out.println("正在导出xlsx...");
    			ExcelUtil.exportExcel(titleList, studentArray, os);
    			System.out.println("导出完成...共" + count + "条数据,用时" + (new Date().getTime() - date.getTime()) + "ms");
    			System.out.println("文件路径:" + file.getAbsolutePath() + "/" + date.getTime() + ".xlsx");
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			os.close();
    		}
    
    	}
    }
    

    4、测试结果:10W条数据导出,用时3s多。






    项目后续更新请移步至:https://github.com/550690513

    Fork me on Github:基于Apache POI导出大数据量Excel的实现

    展开全文
  • maven 依赖 (版本必须一致,否则使用SXSSFworkbook 时...org.apache.poi&lt;/groupId&gt; &lt;artifactId&gt;poi&lt;/artifactId&gt; &lt;version&gt;3.9&lt;/version&gt;
  • 工作中遇到大数据导出excel内存溢出的问题,在使用jxl和POI3.8之前的版本都找不到很好的解决办法,通过设置jvm内存效果也不理想。但是在POI3.8以上版本中提供了SXSSFWorkbook的新类,可以通过参数设置常驻内存中的...
  • POI 导入导出功能,引用jar包是关键,maven依赖支持1.37版. 介绍: 首先,理解一下一个Excel的文件的组织形式,一个Excel文件对应于一个workbook(HSSFWorkbook),一个workbook可以有多个sheet(页/表)...
  • 昨天,产品提了一个紧急需求,让把十一月份已发货的商品数据导...处理程序也在数据导出的过程中写好了,大概思路就是读入Excel构建Workbook对象,然后对指定列的值进行转换,最后写回原文件。想法很奈斯,结果很悲...
  • 一个POI导出Excel万级数据分页实现 解决内存溢出问题 完整的 project demo 有数据库dmp文件
  • java中使用poi导出Excel大批量数据 存在两个导出方法:存在一个分批量导出ZIP文件,一个导出exel文件
  • 使用POI导出大数据量到EXCEL
  • poi导出大数据,先生成多个excel在生成一个jar包
  • POI 提供了 好几种生成Excel的方式,查看官方的API可以发现 第一种:HSSFWorkbook  针对是 EXCEL2003 版本,扩展名为 .xls;所以 此种的局限就是 导出的行数 至多为 65535 行,此种 因为行数不足七万行 所以 一般...
  • 最近公司一个06年统计项目在导出Excel时造成应用服务器内存溢出、假死现象;查看代码发现问题一次查询一整年的数据导致堆内存被撑爆(假死),随后改用批量查询往Excel中写数据,同样的问题又出现了!!!随后在网上...
  • Springboot+poi导出Excel

    2019-03-21 16:44:22
    Springboot+poi导出Excel 一、引入jar包 注意需要引入3.8版本,POI3.8提供了SXSSFWorkbook类,来处理大数据内存溢出的问题.可设置默认内存大小,多出的部分可存入硬盘中,不会内存溢出. <!-- poi依赖 --> <...
  • poi大数据导出excel

    2019-08-02 14:49:48
    由于本人采取的是利用反射的方式,这样的好处,可以兼容,导出所有类型的数据,例如,订单,充值记录等等。 既然是公有的接口,肯定有一定的约束规范。 (1)导出的表头需要自己设置一个动态数组 (2) 头部的宽度...
  • 使用poi导出excel支持xls、xlsx格式大数据导出java工具类,支持同一个单元格不同文本格式。找了好久,加上自己修改后,调试通过,发布出来分享,(调整student类位置)包含所需jar包,工具类,使用示例
  • java中导出excel第一步 创建一个个workbook对象创建一个工作空间设置表格样式第二部 设置标题 设置表列sheet.createRow(rownum++); 创建一行第三部 设置表列sheet.createRow(rownum++);创建一行第四部 创建行对象...
  • poi导出excel最常用的是第一种方式HSSFWorkbook,不过这种方式数据量大的话会产生内存溢出问题,SXSSFWorkbook是一种大数据量导出格式,csv是另一种excel导出的一种轻快的实现。 先介绍一下这三种格式的特点 1...
  • poi导出大数据 1000万

    2017-07-04 16:10:50
    poi大数据导出,千万数据导出,不会内存溢出。
1 2 3 4 5 ... 20
收藏数 746
精华内容 298
关键字:

poi导出excel大数据