百万级别导入导出

pom

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

导入

SheetHandler

/**
 * 自定义的事件处理器
 *  处理每一行数据读取
 *      实现接口
 */
public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler {

    private PoiEntity entity;
    /**
     * 当开始解析某一行的时候触发
     *      i:行索引
     */
    @Override
    public void startRow(int i) {
        //实例化对象
        if(i>0) {
            entity = new PoiEntity();
        }
    }

    /**
     * 当结束解析某一行的时候触发
     *      i:行索引
     */
    @Override
    public void endRow(int i) {
        //使用对象进行业务操作
        System.out.println(entity);
    }

    /**
     * 对行中的每一个表格进行处理
     *      cellReference: 单元格名称
     *      value:数据
     *      xssfComment:批注
     */
    @Override
    public void cell(String cellReference, String value, XSSFComment xssfComment) {
        List matcher = RegUtil.getMatcher("([a-zA-Z]+)", cellReference);
        String pix = matcher.get(0).toString();
        //对对象属性赋值
        if(entity != null) {
            switch (pix) {
                case "A":
                    entity.setId(value);
                    break;
                case "B":
                    entity.setBreast(value);
                    break;
                case "C":
                    entity.setAdipocytes(value);
                    break;
                case "D":
                    entity.setNegative(value);
                    break;
                case "E":
                    entity.setStaining(value);
                    break;
                case "F":
                    entity.setSupportive(value);
                    break;
                default:
                    break;
            }
        }
    }
}

测试

/**
 * 使用事件模型解析百万数据excel报表
 */
public class PoiTest06 {

    public static void main(String[] args) throws Exception {
        long a= System.currentTimeMillis();
        String path = "C:\\Users\\ThinkPad\\Desktop\\ihrm\\day8\\资源\\百万数据报表\\demo.xlsx";
        
        File file = new File(path);
        InputStream inputStream = new FileInputStream(file);
        
        //1.根据excel报表获取OPCPackage
        OPCPackage opcPackage = OPCPackage.open(path, PackageAccess.READ);
        //OPCPackage opcPackage = OPCPackage.open(inputStream);
        //2.创建XSSFReader
        XSSFReader reader = new XSSFReader(opcPackage);
        //3.获取SharedStringTable对象
        SharedStringsTable table = reader.getSharedStringsTable();
        //4.获取styleTable对象
        StylesTable stylesTable = reader.getStylesTable();
        //5.创建Sax的xmlReader对象
        XMLReader xmlReader = XMLReaderFactory.createXMLReader();
        //6.注册事件处理器
        XSSFSheetXMLHandler xmlHandler = new XSSFSheetXMLHandler(stylesTable,table,new SheetHandler(),false);
        xmlReader.setContentHandler(xmlHandler);
        //7.逐行读取
        XSSFReader.SheetIterator sheetIterator = (XSSFReader.SheetIterator) reader.getSheetsData();
        while (sheetIterator.hasNext()) {
            InputStream stream = sheetIterator.next(); //每一个sheet的流数据
            InputSource is = new InputSource(stream);
            xmlReader.parse(is);
        }
        System.out.println("一共耗时:"+(System.currentTimeMillis()-a)/1000);
    }
}

导出

/**
     * 当月人事报表导出
     *  参数:
     *      年月-月(2018-02%)
     */
    @RequestMapping(value = "/export/{month}", method = RequestMethod.GET)
    public void export(@PathVariable String month) throws Exception {
        //1.获取报表数据
        List<EmployeeReportResult> list = userCompanyPersonalService.findByReport(companyId,month);
        //2.构造Excel
        //创建工作簿
        //SXSSFWorkbook : 百万数据报表
        //Workbook wb = new XSSFWorkbook();
        SXSSFWorkbook wb = new SXSSFWorkbook(100); //阈值,内存中的对象数量最大数量
        //构造sheet
        Sheet sheet = wb.createSheet();
        //创建行
        //标题
        String [] titles = "编号,姓名,手机,最高学历,国家地区,护照号,籍贯,生日,属相,入职时间,离职类型,离职原因,离职时间".split(",");
        //处理标题

        Row row = sheet.createRow(0);

        int titleIndex=0;
        for (String title : titles) {
            Cell cell = row.createCell(titleIndex++);
            cell.setCellValue(title);
        }

        int rowIndex = 1;
        Cell cell=null;
        for(int i=0;i<10000;i++){
        for (EmployeeReportResult employeeReportResult : list) {
            row = sheet.createRow(rowIndex++);
            // 编号,
            cell = row.createCell(0);
            cell.setCellValue(employeeReportResult.getUserId());
            // 姓名,
            cell = row.createCell(1);
            cell.setCellValue(employeeReportResult.getUsername());
            // 手机,
            cell = row.createCell(2);
            cell.setCellValue(employeeReportResult.getMobile());
            // 最高学历,
            cell = row.createCell(3);
            cell.setCellValue(employeeReportResult.getTheHighestDegreeOfEducation());
            // 国家地区,
            cell = row.createCell(4);
            cell.setCellValue(employeeReportResult.getNationalArea());
            // 护照号,
            cell = row.createCell(5);
            cell.setCellValue(employeeReportResult.getPassportNo());
            // 籍贯,
            cell = row.createCell(6);
            cell.setCellValue(employeeReportResult.getNativePlace());
            // 生日,
            cell = row.createCell(7);
            cell.setCellValue(employeeReportResult.getBirthday());
            // 属相,
            cell = row.createCell(8);
            cell.setCellValue(employeeReportResult.getZodiac());
            // 入职时间,
            cell = row.createCell(9);
            cell.setCellValue(employeeReportResult.getTimeOfEntry());
            // 离职类型,
            cell = row.createCell(10);
            cell.setCellValue(employeeReportResult.getTypeOfTurnover());
            // 离职原因,
            cell = row.createCell(11);
            cell.setCellValue(employeeReportResult.getReasonsForLeaving());
            // 离职时间
            cell = row.createCell(12);
            cell.setCellValue(employeeReportResult.getResignationTime());
        }
        }
        //3.完成下载
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        wb.write(os);
        new DownloadUtils().download(os,response,month+"人事报表.xlsx");
    }

下载类DownloadUtils

import org.apache.poi.ss.usermodel.Workbook;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class DownloadUtils {
    public void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException {
        response.setContentType("application/octet-stream");
        returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1"));            //保存的文件名,必须和页面编码一致,否则乱码
        response.addHeader("Content-Disposition","attachment;filename=total.xls");
        response.setContentLength(byteArrayOutputStream.size());
        response.addHeader("Content-Length", "" + byteArrayOutputStream.size());
        ServletOutputStream outputstream = response.getOutputStream();    //取得输出流
        byteArrayOutputStream.writeTo(outputstream);                    //写到输出流
        byteArrayOutputStream.close();                                    //关闭
        outputstream.flush();                                            //刷数据
    }
}

2.注解导出

第一步:需要定义注解类

ExcelAttribute.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Description
 * @auther 刘中华
 * @create 2019-03-15 11:31
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAttribute {
    /** 对应的列名称 */
    String name() default "";

    /** 列序号 */
    int sort();

    /** 字段类型对应的格式 */
    String format() default "";

}

ExcelAttributeHandle 需要特殊处理的类,比如说男女我们在数据库存的是0和1,导出的肯定不能是01,肯定是男女
/**
 * @Description
 * @auther 刘中华
 * @create 2019-03-15 13:47
 */
public class ExcelAttributeHandle {

    public static final String TIME="time";
    public static final String SIGN="sign";

    public static String handle(String type, Object val){
        String format= null;
        switch (type){
            case "time":
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                System.out.println(val.getClass());
                format = simpleDateFormat.format(val);
                break;
            case "sign":
                format=Integer.valueOf(val.toString())==0?"流入":"流出";
                break;
        }
        return format;
    }
}

第二步:定义要导出的类

import com.mairuide._frame.utils.excel.annotation.ExcelAttribute;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 * @Description
 * @auther 刘中华
 * @create 2019-03-15 14:48
 */
public class ExceptionAnalysisDetail implements Serializable {
    /**
     * 交易主体
     */
    @ExcelAttribute(name = "交易主体",sort = 0)
    private String account_body;
    /**
     * 交易主体卡号
     */
    @ExcelAttribute(name = "交易主体卡号",sort = 1)
    private String account_body_card;
    /**
     * 交易对手
     */
    @ExcelAttribute(name = "交易对手",sort = 2)
    private String account_rival;

    /**
     * 交易主体卡号
     */
    @ExcelAttribute(name = "交易对手卡号",sort = 3)
    private String account_rival_card;

    /**
     * 时间段
     */
    @ExcelAttribute(name = "交易日期间隔",sort = 4)
    private String time_slot;

    /**
     * 总交易金额
     */
    @ExcelAttribute(name = "总交易金额",sort = 5)
    private BigDecimal sum_account_money;

    @ExcelAttribute(name = "交易次数",sort = 6)
    private Integer trade_count;
ExcelExportUtil导出类
import com.mairuide._frame.utils.excel.annotation.ExcelAttribute;
import com.mairuide._frame.utils.excel.annotation.ExcelAttributeHandle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.List;

public class ExcelExportUtil<T> {

    private int rowIndex;
    private int styleIndex;
    private String templatePath;
    private Class clazz;
    private  Field fields[];
    private String[] letter = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};

    public ExcelExportUtil(Class clazz) {
        this.clazz = clazz;
        fields = clazz.getDeclaredFields();
    }

    /**
     * 基于注解导出
     */
    public void export(HttpServletResponse response, List<T> objs,String fileName) throws Exception {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet();
        Row title_row = sheet.createRow(0);
        int cellIndex=0;
        for (int k = 0; k < fields.length; k++) {
            Cell cell = title_row.createCell(k);
            ExcelAttribute ea = fields[k].getAnnotation(ExcelAttribute.class);
            if(ea!=null && k == ea.sort()) {
                String name = ea.name();
                cell.setCellValue(name);
                cellIndex=k;
            }
        }
        String addStr = "A0:"+letter[cellIndex]+"0";
        CellRangeAddress addr = CellRangeAddress.valueOf(addStr);
        sheet.setAutoFilter(addr);
        for (int i = 0; i <objs.size() ; i++) {
            Row row = sheet.createRow(i+1);
            for (int j = 0; j <fields.length ; j++ ) {
                Cell cell = row.createCell(j);
                if(fields[j].isAnnotationPresent(ExcelAttribute.class)){
                    fields[j].setAccessible(true);
                    ExcelAttribute ea = fields[j].getAnnotation(ExcelAttribute.class);
                    if(ea!=null && j == ea.sort()&&fields[j].get(objs.get(i))!=null) {
                        if (ea.format()!=null&&!ea.format().equals("")){
                            cell.setCellValue(ExcelAttributeHandle.handle(ea.format(),fields[j].get(objs.get(i)).toString()));
                        }else{
                            cell.setCellValue(fields[j].get(objs.get(i)).toString());
                        }
                    }
                }
            }
        }
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setContentType("application/octet-stream");
        response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes("ISO8859-1")));
        response.setHeader("filename", fileName);
        workbook.write(response.getOutputStream());
    }

    public int getRowIndex() {
        return rowIndex;
    }

    public void setRowIndex(int rowIndex) {
        this.rowIndex = rowIndex;
    }

    public int getStyleIndex() {
        return styleIndex;
    }

    public void setStyleIndex(int styleIndex) {
        this.styleIndex = styleIndex;
    }

    public String getTemplatePath() {
        return templatePath;
    }

    public void setTemplatePath(String templatePath) {
        this.templatePath = templatePath;
    }

    public Class getClazz() {
        return clazz;
    }

    public void setClazz(Class clazz) {
        this.clazz = clazz;
    }

    public Field[] getFields() {
        return fields;
    }

    public void setFields(Field[] fields) {
        this.fields = fields;
    }
}

调用方法:

 //第一步 得到数据
 List list = getlist.getRows();
//第二步 下载excel
Class clazz= ExceptionAnalysisDetail.class;
new ExcelExportUtil(clazz).export(response,list,"异常资金分析.xlsx");

猜你喜欢

转载自www.cnblogs.com/coder-lzh/p/10746879.html