SpringBoot в сочетании с операцией отчета о данных на уровне миллиона точек интереса

Расширенные операции отчета о точках входа

В предыдущей статье говорилось, что Excel можно разделить на две версии: Excel2003 и Excel2007. Excel2003 использует объекты HSSF в POI. На листе можно разместить до 65536 элементов данных. Его можно использовать при обработке меньшего объема данных, но Excel2003 определенно не может вместить при обработке миллионов данных. ; Excel2007 использует объекты XSSF в POI, позволяя на листе хранить не более 1048576 частей данных, что указывает на то, что он может поддерживать миллионы данных, но при реальной работе могут возникать проблемы. Причина в том, что объекты, генерируемые отчетами POI, объектами ячеек, Объекты шрифтов не будут уничтожены, что приведет к возможному риску переполнения памяти OutOfMemoryError (OOM).

Обзор экспорта отчетов о миллионах данных

Для экспорта миллионов данных Excel в основном обсуждают только использование версии Excel2007. ApachePOI предоставляет три способа решить проблему импорта и экспорта больших объемов данных:

  • Пользовательский режим: пользовательский режим имеет множество инкапсулированных методов, которыми легко управлять, но которые создают слишком много объектов и потребляют огромную память.
  • Режим событий: синтаксический анализ XML на основе SAX (простой API для XML) представляет собой интерфейс и программный пакет. Это альтернатива синтаксическому анализу XML. Отличие от синтаксического анализа DOM заключается в том, что он анализирует строку за строкой и не загружает все данные сразу. Память эквивалентна анализу при сканировании.
  • Объект SXSSF: используется для создания большого количества файлов Excel, в основном с временным пространством для хранения для создания Excel.

    Экспорт миллионов данных

анализ спроса

В эпоху Интернета часто генерируются миллионы данных, и есть разные причины для экспорта данных.

Решение

  • 1. Анализ мышления:

Использование объекта POI XSSFWORK для экспорта отчетов Excel заключается в передаче всех данных в объект ячейки за один раз и их сохранении в памяти.Когда все ячейки будут созданы, они будут записаны в Excel для одновременного экспорта. При достижении экспорта миллионов данных, с непрерывным созданием объектов ячеек, все больше и больше данных в памяти, вплоть до OOM. Объект SXSSFWORK POI специально экспортируется из Excel для обработки больших объемов данных.

2. Принцип анализа:

При создании экземпляра объекта SXSSFWork вы можете указать количество объектов POI, сгенерированных в памяти (по умолчанию 100). Как только количество объектов памяти достигает указанного числа, данные в памяти записываются на диск, и данные в памяти могут быть уничтожены Цикл до завершения экспорта в Excel

Код

Возьмем для примера пользовательские данные

Добавить в FileUtil

Внесены незначительные изменения в предыдущий

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());

    }
}

Настроить в контроллере

 @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);
    }

Заключение:

Первоначально я хотел представить экспорт данных, но обнаружил, что также необходимо ввести экспорт миллионов данных. Я представлю экспорт данных завтра.

Адрес Github:

адрес на github: https://github.com/bangbangzhou/greemes/tree/master

публика

SpringBoot в сочетании с операцией отчета о данных на уровне миллиона точек интереса

рекомендация

отblog.51cto.com/15077535/2593725
рекомендация