SpringBoot combinado con operaciones de informes de datos de niveles de millones de puntos de interés

Funcionamiento avanzado del informe de puntos de interés

El artículo anterior ha introducido que Excel se puede dividir en dos versiones: Excel2003 y Excel2007. Excel2003 usa objetos HSSF en POI. Una hoja permite hasta 65536 elementos de datos. Se puede usar cuando se procesan menos datos, pero Excel2003 ciertamente no se puede acomodar al procesar millones de datos. ; Excel2007 usa objetos XSSF en POI, lo que permite que una hoja almacene 1048576 piezas de datos como máximo, lo que indica que puede admitir millones de datos, pero puede haber problemas en el funcionamiento real. La razón es que los objetos generados por informes de POI, objetos de celda, Los objetos de fuente no se destruirán, lo que provocará un posible riesgo de desbordamiento de memoria OutOfMemoryError (OOM).

Descripción general de la exportación de informes de millones de datos

Para la exportación de millones de datos a Excel, básicamente solo se comenta el uso de la versión Excel2007. ApachePOI proporciona tres formas de resolver la importación y exportación de grandes cantidades de datos:

  • Modo de usuario: el modo de usuario tiene muchos métodos encapsulados, que son fáciles de operar, pero crean demasiados objetos y consumen mucha memoria
  • Modo de evento: el análisis de XML basado en SAX (API simple para XML) es una interfaz y un paquete de software. Es una alternativa al análisis de XML. La diferencia con el análisis de DOM es que analiza línea por línea y no carga todos los datos a la vez. La memoria es equivalente a analizar mientras se escanea.
  • Objeto SXSSF: se utiliza para generar una gran cantidad de archivos de Excel, principalmente con espacio de almacenamiento temporal para generar Excel

    Exportación de millones de datos

análisis de demanda

En la era de Internet, a menudo se generan millones de datos y existen varias razones para la exportación de datos.

Solución

  • 1. Análisis de pensamiento:

El uso del objeto XSSFWORK de POI para exportar informes de Excel es transferir todos los datos al objeto de celda a la vez y guardarlos en la memoria.Cuando se crean todas las celdas, se escribirán en Excel para exportarlas a la vez. Al llegar a la exportación de millones de datos, con la creación continua de objetos de celda, cada vez más datos en la memoria, hasta OOM. El objeto SXSSFWORK de POI se exporta especialmente desde Excel para manejar grandes cantidades de datos.

2. Análisis de principios:

Al crear una instancia del objeto SXSSFWork, puede especificar el número de objetos POI generados en la memoria (por defecto 100). Una vez que el número de objetos de la memoria alcanza el número especificado, los datos en la memoria se escriben en el disco y los datos en la memoria se pueden destruir Para repetir hasta que se complete la exportación a Excel

Código

Tome los datos del usuario como ejemplo

Agregar en FileUtil

Hizo algunos cambios menores al anterior.

package com.cn.greemes.common.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil;
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.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 文件操作
 */
public class FileUtil {

    public static final String SYS_TEM_DIR =System.getProperty("java.io.tmpdir")+ File.separator;

    public  void downloadExcel(List<Map<String, String>> list, HttpServletResponse response) throws IOException {
        String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx";
        File file = new File(tempPath);
        BigExcelWriter writer = ExcelUtil.getBigWriter(file);
        // 一次性写出内容,使用默认样式,强制输出标题
        writer.write(list, true);
        SXSSFSheet sheet = (SXSSFSheet)writer.getSheet();
        //上面需要强转SXSSFSheet  不然没有trackAllColumnsForAutoSizing方法
        sheet.trackAllColumnsForAutoSizing();
        //列宽自适应
       // writer.autoSizeColumnAll();
        //response为HttpServletResponse对象
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename=file.xlsx");
        ServletOutputStream out = response.getOutputStream();
        // 终止后删除临时文件
        file.deleteOnExit();
        writer.flush(out, true);
        //此处记得关闭输出Servlet流
        IoUtil.close(out);
    }

    public  void downloadExcelBySXSSF(List<Map<String, String>> list, HttpServletResponse response) throws IOException {
        String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx";
        File file = new File(tempPath);
        //2.创建工作簿
         SXSSFWorkbook workbook = new SXSSFWorkbook();
        //3.构造sheet
        Sheet sheet =workbook.createSheet();
        //创建表头
        Row row = sheet.createRow(0);
        Map<String,String> mapfirst = list.get(0);

        String listHead = null;
        AtomicInteger headersAi = new AtomicInteger();

        for (String key : mapfirst.keySet()) {
           Cell cell = row.createCell(headersAi.getAndIncrement());

           cell.setCellValue(key);
        }
        AtomicInteger datasAi = new AtomicInteger(1);
        Cell cell =null;
        for(Map<String, String> map : list){
            Row dataRow = sheet.createRow(datasAi.getAndIncrement());
            int i=0;
            for (String key : map.keySet()) {
                Cell cell1 = dataRow.createCell(datasAi.getAndIncrement());
                String value= (String)map.get(key);
                cell = dataRow.createCell(i);
                cell1.setCellValue(value);
                i++;
            }
        }
        String fileName = URLEncoder.encode("用户信息.xlsx", "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());

    }
}

Configurar en el controlador

 @ApiOperation("导出用户数据")
    @RequestMapping(value = "/export2", method = RequestMethod.GET)
    @ResponseBody
    public void export2(HttpServletResponse response, @RequestParam(value = "keyword", required = false) String keyword,
                       @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
                       @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) throws UnsupportedEncodingException, IOException {
        Page<MesAdmin> adminList = adminService.list(keyword, pageSize, pageNum);

        List<Map<String,String>> list = new ArrayList();
        //因为只有七条数据,所以做了多次循环添加数据
        for(int i=0;i<149795;i++) {
            for (MesAdmin umsAdmin : adminList.getRecords()) {
                Map<String, String> map = new HashMap<>(6);
                DateFormat d1 = DateFormat.getDateInstance();
                map.put("姓名", umsAdmin.getUsername());
                map.put("邮箱", umsAdmin.getEmail());
                map.put("昵称", umsAdmin.getNickName());
                map.put("备注信息", umsAdmin.getNote());
                map.put("创建时间", d1.format( umsAdmin.getCreateTime()));
                String loginTime ="";
                if(umsAdmin.getLoginTime()!=null){
                    loginTime=d1.format( umsAdmin.getLoginTime());
                }
                map.put("最后登录时间",loginTime );
                list.add(map);
            }
        }

        fileUtil.downloadExcelBySXSSF(list,response);
    }

Conclusión:

Originalmente quería introducir la exportación de datos, pero descubrí que también es necesario introducir la exportación de millones de datos. Mañana presentaré la exportación de datos.

Dirección de Github:

Dirección de github: https://github.com/bangbangzhou/greemes/tree/master

el público

SpringBoot combinado con operaciones de informes de datos de niveles de millones de puntos de interés

Supongo que te gusta

Origin blog.51cto.com/15077535/2593725
Recomendado
Clasificación