精华内容
下载资源
问答
  • easyExcel分批导入文件

    2021-04-25 21:46:43
    一些关于easyExcel导入文件操作 需求: 导入大数据量文件 其中数据达到万级、十万级, 错误文件进行错误单元格标红, 可导出修改完继续导入 由于数据量多大 一次行全部读到内存中可能会导致内存溢出问题 使用...

    一些关于easyExcel导入文件操作

    需求: 导入大数据量文件 其中数据达到万级、十万级, 错误文件进行错误单元格标红, 可导出修改完继续导入

    由于数据量多大 一次行全部读到内存中可能会导致内存溢出问题

    使用easyExcel poi的监听器进行操作

     

    三步曲:

    1、解析excel为inputStream流, 读取流,解析excel

    2、判断excel中每条数据的格式, 正确和错误相对记录

    3、通过监听器每解析150条数据, 进行入库操作, 错误数据存在内存中(考虑错误数据不多的情况)

    // 这里用到ossfs 反正就是读取excel为input流,
    涉及到两个系统之间流的传输, 这里直接把文件上传到oss
    try {
        in = new FileInputStream(localFileName);
    } catch (FileNotFoundException e) {
        in = HttpUtil.io(HttpUtil.Atom.builder().url(diseaseDto.getFileUrl()).build());
    }
    // 这里解析excel其中
    OltHosIcdDiseaseListener为自定义监听器
    try {
        LoggerUtil.info(LOGGER, "开始解析IcdDisease");
        OltHosIcdDiseaseListener oltHosIcdDiseaseListener = new OltHosIcdDiseaseListener(isCfgPrd, icdCodeList, delIcdCodeList, diseaseDto, oltConfigService, exportTaskHandler);
        excelReader = EasyExcel.read(in, oltHosIcdDiseaseListener).build();
        ReadSheet readSheet = EasyExcel.readSheet(0).build();
        excelReader.read(readSheet);
    } finally {
        try {
            if (in != null) {
                in.close();
            }
            if (excelReader != null) {
                // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
                excelReader.finish();
            }
        } catch (Exception e) {
            LoggerUtil.error(LOGGER, "{0},{1}", e.getMessage(), e);
        }
    }
    // 通过构造函数, 初始化一些list与对象
    // 这个是导入的核心方法, 所有的导入逻辑, 判断逻辑与入库都在这里操作
    // 采用无对象方式
    @Slf4j
    public class OltHosIcdDiseaseListener extends AnalysisEventListener<Map<Integer, String>> {
        private OltConfigService oltConfigService;
        private ExportTaskHandler exportTaskHandler;
        private static final int batchCount = 150;
        private int countNum = 0;
        private boolean isCfgPrd;
        private int successCount = 0;
        private int errorCount = 0;
    
        private List<String> checkRepeatCode = new ArrayList<>();
        private List<String> icdCodeList;
        private List<String> delIcdCodeList;
        private OltHosIcdDiseaseDto diseaseDto;
        private List<OltHosIcdDiseaseDto> successList = new ArrayList<>();
        private List<OltHosIcdDiseaseDto> errorList = new ArrayList<>();
        private List<OltHosIcdDiseaseDto> tempErrorList = new ArrayList<>();
    
    
        public OltHosIcdDiseaseListener(boolean isCfgPrd, List<String> icdCodeList, List<String> delIcdCodeList, OltHosIcdDiseaseDto diseaseDto,
                                        OltConfigService oltConfigService, ExportTaskHandler exportTaskHandler) {
            this.isCfgPrd = isCfgPrd;
            this.icdCodeList = icdCodeList;
            this.delIcdCodeList = delIcdCodeList;
            this.diseaseDto = diseaseDto;
            this.oltConfigService = oltConfigService;
            this.exportTaskHandler = exportTaskHandler;
        }
    
    /**
      * 这个每一条数据解析都会来调用
      * data --> 实体类
      * analysisContext excel信息
     */
    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext context) {
        int rouNumber = context.readRowHolder().getRowIndex() + 1;
    
        // 这里是因为表头在第二行
        if (rouNumber == 2) {
            // 这里是校验表头
            checkExcelHead(data);
        } else if (rouNumber > 2) {
            // 这里是校验数据
            checkReadData(data);
        }
    
        // 超过150条就先入库
        if (countNum >= batchCount) {
            // 处理excel导出的正确数据
            batchOperateData();
        }
        countNum++;
    }
    
    /**
     * @author songhc
     * @create 
     * @desc 调用完成监听, 确保数据已全部处理完
     **/
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        Map<String, Object> objMap = new HashMap<>();
        // 处理excel导出的正确数据
        batchOperateData();
    
        // 错误数据填充oss表格
        Object object = uploadErrorData(errorList, diseaseDto);
    
        objMap.put("errorInfo", object);
        objMap.put("successCount", successCount);
        objMap.put("errorCount", errorCount);
    
        // 错误数据记录redis, 下次使用
        RedisStringHandler.set(String.format(RedisKeyConstants.EXPORT_ERROR_RESULT, "disease" + diseaseDto.getUserId() + "_" + diseaseDto.getRgId() + "_" + diseaseDto.getHosId()), JSONObject.toJSONString(objMap));
    }
    
    // 这里是封装所有的错误数据
    // 包括封装单元格
    private Object uploadErrorData (List<OltHosIcdDiseaseDto> errorList, OltHosIcdDiseaseDto dto) {
        Map<Integer, List<Integer>> map = new HashMap<>();
        LinkedList<OltHosIcdDiseaseDto> newErrorList = new LinkedList<>();
        if (CollectionUtils.isNotEmpty(errorList)) {
            for (int i = 0; i < errorList.size(); i++) {
                OltHosIcdDiseaseDto e = errorList.get(i);
                List<Integer> integerList = new ArrayList<>();
                if (e.getErrorReasonMap() != null && !e.getErrorReasonMap().isEmpty()) {
                    List<String> reasonList = new ArrayList<>();
                    for (Integer key: e.getErrorReasonMap().keySet()) {
                        // 标红单元格
                        integerList.add(key);
                        reasonList.add(e.getErrorReasonMap().get(key));
                    }
                    map.put(i + 2, integerList);
                    e.setErrorReason(String.join("、", reasonList));
                }
                newErrorList.add(e);
            }
        }
    
    
        // 封装导出服务入参
        String uuid = UUIDUtil.create();
        String errorFileName = dto.getHosName() + "(待处理诊断数据)" + dto.getStatDataStr() + ".xlsx";
        SysExportRecordDto sysExportRecordDto = SysExportRecordDto.builder().batchId(uuid).userId(dto.getUserId()).pfCode(dto.getPfCode())
                .source(dto.getSource()).fileName(errorFileName).creator(dto.getCreator()).operator(dto.getCreator()).build();
        // 创建导出记录
        QueueHandler.createTaskRecord(sysExportRecordDto);
        // 获取url
        // 伪代码
        String fileName = "aaa.xlsx";
        String BUCKET_NAME = "bbb";
        String fileUrl = String.format(OssClientConfig.OSS_REAL_PATH, BUCKET_NAME,
                UploadFileType.getFolderByType(UploadFileType.REPORT)).concat(fileName);
        // 加入异步线程任务
        this.exportTaskHandler.exportIcdErrorDiseaseData(OltErrorResult.builder().map(map).errorList(newErrorList)
                        .fileName(errorFileName).source(dto.getSource()).build(),
                uuid, errorFileName, fileUrl);
        // 构建返回队列信息
        return QueueHandler.buildQueueInfo(sysExportRecordDto);
    }
    
    private void batchOperateData() {
        checkErrorExcelList(tempErrorList, icdCodeList);
        checkSuccessExcelList(successList, tempErrorList, icdCodeList);
    
        // 将临时错误数据存储到所有错误数据列表
        this.errorList.addAll(tempErrorList);
        // 清理list
        this.successList.clear();
        this.tempErrorList.clear();
        this.countNum = 0;
    }
    
    private void checkExcelHead(Map<Integer, String> data) {
        boolean templateFlag = true;
        // 第二行  校验excel标题
        try {
            String diseaseCategoryStr = data.get(0);
            if (StringUtils.isBlank(diseaseCategoryStr) || !"诊eee(必填)".equals(diseaseCategoryStr)) {
                templateFlag = false;
            }
        } catch (Exception e) {
            templateFlag = false;
        }
        try {
            String icdNameStr = data.get(1);
            if (StringUtils.isBlank(icdNameStr) || !"医vv称(必填)".equals(icdNameStr)) {
                templateFlag = false;
            }
        } catch (Exception e) {
            templateFlag = false;
        }
        try {
            String icdCodeStr = data.get(2);
            if (StringUtils.isBlank(icdCodeStr) || !"医aa(必填)".equals(icdCodeStr)) {
                templateFlag = false;
            }
        } catch (Exception e) {
            templateFlag = false;
        }
        if (!templateFlag) {
            throw new PlatException("文件模版不匹配");
        }
    }
    
    private void checkReadData(Map<Integer, String> data) {
        // 循环cell
        OltHosIcdDiseaseDto temDisDto = OltHosIcdDiseaseDto.buildDefault();
        temDisDto.setHosId(diseaseDto.getHosId());
        // key为所在的列, value为错误原因
        Map<Integer, String> map = new HashMap<>();
        boolean flag = true;
        try {
            // 解析第二列
            String diseaseCategory = data.get(0);
            if (StringUtils.isBlank(diseaseCategory)) {
                temDisDto.setDiseaseCategoryStr(StringUtils.EMPTY);
                map.put(0, "aaa为空");
                flag = false;
            } else {
                temDisDto.setDiseaseCategoryStr(diseaseCategory);
            }
        } catch (Exception e) {
            temDisDto.setDiseaseCategoryStr(StringUtils.EMPTY);
            map.put(0, "bbb为空");
            flag = false;
        }
    
        try {
            String icdName = data.get(1);
            if (StringUtils.isBlank(icdName)) {
                temDisDto.setIcdName(StringUtils.EMPTY);
                map.put(1, "为空");
                flag = false;
            } else {
                temDisDto.setIcdName(icdName);
            }
        } catch (Exception e) {
            temDisDto.setIcdName(StringUtils.EMPTY);
            map.put(1, "ccc称为空");
            flag = false;
        }
    
        try {
            String icdCode = data.get(2);
            if (StringUtils.isBlank(icdCode)) {
                temDisDto.setIcdCode(StringUtils.EMPTY);
                map.put(2, "ddd为空");
                flag = false;
            } else {
                temDisDto.setIcdCode(icdCode);
            }
        } catch (Exception e) {
            temDisDto.setIcdCode(StringUtils.EMPTY);
            map.put(2, "ddd为空");
            flag = false;
        }
    
    
        try {
            if (!DiseaseCategory.TCM_SYNDROME.getDesc().equals(temDisDto.getDiseaseCategoryStr())) {
                String standardIcdName = data.get(3);
                if (isCfgPrd && StringUtils.isBlank(standardIcdName)) {
                    temDisDto.setStandardIcdName(StringUtils.EMPTY);
                    map.put(3, "vvv为空");
                    flag = false;
                } else {
                    temDisDto.setStandardIcdName(standardIcdName);
                }
            }
        } catch (Exception e) {
            temDisDto.setStandardIcdName(StringUtils.EMPTY);
            map.put(3, "vvv为空");
            flag = false;
        }
    
        try {
            if (!DiseaseCategory.TCM_SYNDROME.getDesc().equals(temDisDto.getDiseaseCategoryStr())) {
                String standardIcdCode = data.get(4);
                if (isCfgPrd && StringUtils.isBlank(standardIcdCode)) {
                    temDisDto.setStandardIcdCode(StringUtils.EMPTY);
                    map.put(4, "eee为空");
                    flag = false;
                } else {
                    temDisDto.setStandardIcdCode(standardIcdCode);
                }
            }
        } catch (Exception e) {
            temDisDto.setStandardIcdCode(StringUtils.EMPTY);
            map.put(4, "eee为空");
            flag = false;
        }
        temDisDto.setErrorReasonMap(map);
    
    
        // 如果flag为 false 说明数据有问题
        if (!flag) {
            tempErrorList.add(temDisDto);
        } else {
            successList.add(temDisDto);
        }
    }
    
    private void checkErrorExcelList(List<OltHosIcdDiseaseDto> errorList, List<String> icdCodeList) {
        if (CollectionUtils.isNotEmpty(errorList)) {
            // 错误就往里加, 正确重新定义列表
            errorList.forEach(e -> {
                Map<Integer, String> map = new HashMap<>();
                if (!DiseaseCategory.belongTo(e.getDiseaseCategoryStr())) {
                    map.put(0, "aaa不正确");
                } else {
                    e.setDiseaseCategory(DiseaseCategory.getCodeByDesc(e.getDiseaseCategoryStr()));
                }
                
                // excel是否存在重复数据
                if (checkRepeatCode.contains(e.getIcdCode())) {
                    map.put(2, "bbb重复");
                }
    
                if (CollectionUtils.isNotEmpty(icdCodeList) && icdCodeList.contains(e.getIcdCode())) {
                    map.put(2, "ttt重复");
                }
                if (e.getErrorReasonMap() != null && !e.getErrorReasonMap().isEmpty()) {
                    Map<Integer, String> errorReasonMap = e.getErrorReasonMap();
                    errorReasonMap.putAll(map);
                    e.setErrorReasonMap(errorReasonMap);
                }
                errorCount++;
            });
        }
    }
    
    /**
     * 侵入式给errorList赋值
     * @param list
     * @param errorList
     * @param icdCodeList
     */
    private void checkSuccessExcelList(List<OltHosIcdDiseaseDto> list, List<OltHosIcdDiseaseDto> errorList,
                                       List<String> icdCodeList) {
        List<OltHosIcdDiseaseDto> newList = new ArrayList<>();
    
        if (CollectionUtils.isNotEmpty(list)) {
            // 错误就往里加, 正确重新定义列表
            list.forEach(e -> {
                Map<Integer, String> map = new HashMap<>();
                boolean flag = false;
                // 判
                if (!DiseaseCategory.belongTo(e.getDiseaseCategoryStr())) {
                    map.put(0, "不正确");
                    flag = true;
                } else {
                    e.setDiseaseCategory(DiseaseCategory.getCodeByDesc(e.getDiseaseCategoryStr()));
                }
    
                // excel是否存在重复数据
                if (checkRepeatCode.contains(e.getIcdCode())) {
                    map.put(2, "重复");
                    flag = true;
                } else {
                    // 判断诊断编码
                    if (CollectionUtils.isNotEmpty(icdCodeList) && icdCodeList.contains(e.getIcdCode())) {
                        map.put(2, "重复");
                        flag = true;
                    }
                }
                e.setErrorReasonMap(map);
                if (flag) {
                    errorCount++;
                    errorList.add(e);
                } else {
                    e.setIcdPinyin(HzUtils.getPinyinCap(e.getIcdName(), HzUtils.CaseType.UPPERCASE));
                    e.setIcdWb(HzUtils.getWbCap(e.getIcdName(), HzUtils.CaseType.UPPERCASE));
                    newList.add(e);
                    checkRepeatCode.add(e.getIcdCode());
                    successCount++;
                }
            });
        }
    
        // 正确数据入库
        if (CollectionUtils.isNotEmpty(newList)) {
            oltConfigService.batchAddHosIcdDisease(delIcdCodeList, newList);
        }
    }

    其中,导入错误数据用了easyExcel的模版填充方式, 模版存于oss上

    
    
    
    /**
     * @author songhc
     * @create
     * @desc 导出错误数据
     **/
    @Async
    public void exportIcdErrorDiseaseData(OltErrorResult dto, String fileBatch, String fileName, String fileUrl) {
        Map<Integer, List> map = new HashMap<>();
        map.put(0, dto.getErrorList());
        Map<Integer, Map<Integer, List<Integer>>> styleMap = new HashMap<>();
        styleMap.put(0, dto.getMap());
        ExportExistHandler.exportExistTemplateData(map, styleMap, fileBatch, fileName, fileUrl);
    }

    接下来就是填充错误模版的实现

    /**
     * @param errorMap key为sheetNo, value为填充的数据
     * @param styleMap key为sheetNo, value为错误数据坐标
     * @param fileBatch 批次号
     * @param fileName 文件名
     * @param fileUrl 文件路径
     * @description 导出服务封装方法(无需分页查询, 数据为动态传入)
     * @className exportNoModelData
     */
    public static void exportExistTemplateData(Map<Integer, List> errorMap, Map<Integer, Map<Integer, List<Integer>>> styleMap, String fileBatch, String fileName, String fileUrl) {
        String ossFileName = fileName.substring(0, fileName.lastIndexOf('.'))
                .concat("-").concat(LocalDateTime.now()
                        .format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))).concat(fileName.substring(fileName.lastIndexOf('.')));
        InputStream inputStream = HttpUtil.io(HttpUtil.Atom.builder().url(fileUrl).build());
        if (null == inputStream) {
            return;
        }
        String localFileName = String.format(TaskNoteHandler.staticExportConfig.getExportPath(), ossFileName);
        ExcelWriter excelWriter = null;
        int resultCount = 0;
        try {
            if (errorMap != null && !errorMap.isEmpty()) {
                excelWriter = EasyExcel.write(localFileName)
                            .withTemplate(inputStream)
                            .build();
                // for循环是一个excel可能有多个sheet的兼容写法
                for (Integer i: errorMap.keySet()) {
                    // 这里使用easyExcel的 registerWriteHandler 方法, 自定义CellColorSheetWriteHandler实现, 给每一个单元格填充颜色
                    WriteSheet writeSheet = EasyExcel.writerSheet(i).registerWriteHandler(new CellColorSheetWriteHandler(styleMap.get(i),
                            IndexedColors.RED1.getIndex())).build();
                    excelWriter.fill(errorMap.get(i), writeSheet);
                }
            }
        } catch (Exception e){
            LoggerUtil.error(LOGGER, "文件写入异常,error{0}", e);
            // 文件导出失败
            TaskNoteHandler.doUploadFailed(fileBatch, resultCount);
            return;
        } finally {
            // 关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
        // 1、上传文件(多种方案);2、更新记录
        TaskNoteHandler.doUploadAndNote(fileBatch, ossFileName, localFileName, resultCount);
    }
    /**
     * @description 自定义单元格格式拦截器
     * @className CellColorSheetWriteHandler
     * @package 
     * @Author songhc
     */
    public class CellColorSheetWriteHandler implements CellWriteHandler {
    
        /**
         * map
         * key:第i行
         * value:第i行中单元格索引集合
         */
        private Map<Integer, List<Integer>> map;
    
        /**
         * 颜色
         */
        private Short colorIndex;
    
        /**
         * 有参构造
         */
        public CellColorSheetWriteHandler(Map<Integer, List<Integer>> map, Short colorIndex) {
            this.map = map;
            this.colorIndex = colorIndex;
        }
    
        /**
         * 无参构造
         */
        public CellColorSheetWriteHandler() {
        }
    
        @Override
        public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {
        }
    
        /**
         * 在单元格创建后调用
         */
        @Override
        public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {
        }
    
        @Override
        public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
        }
    
        /**
         * 在单元上的所有操作完成后调用
         */
        @Override
        public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
            //当前行的第i列
            int i = cell.getColumnIndex();
            // 根据单元格获取workbook
            Workbook workbook = cell.getSheet().getWorkbook();
            //不处理第一行
            if (0 != cell.getRowIndex()) {
                List<Integer> integerList = map.get(cell.getRowIndex());
                // 自定义单元格样式 
                if (CollectionUtils.isNotEmpty(integerList)) {
                    if (integerList.contains(i)) {
                        // 单元格策略
                        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
                        // 设置背景颜色白色
                        contentWriteCellStyle.setFillForegroundColor(colorIndex);
                        // 设置垂直居中为居中对齐
                         contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                        // 设置左右对齐为中央对齐
                         contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.RIGHT);
                        // 设置单元格上下左右边框为细边框
                          contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
                          contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
                         contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
                         contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
                        // 创建字体实例
                         WriteFont cellWriteFont = new WriteFont();
                        // 设置字体大小
                         cellWriteFont.setFontName("宋体");
                         cellWriteFont.setFontHeightInPoints((short) 10);
                        //设置字体颜色
                        // cellWriteFont.setColor(IndexedColors.BLACK1.getIndex());
                        //单元格颜色
                        //contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
                        contentWriteCellStyle.setWriteFont(cellWriteFont);
                        CellStyle cellStyle = StyleUtil.buildHeadCellStyle(workbook, contentWriteCellStyle);
                        //设置当前行第i列的样式
                        cell.getRow().getCell(i).setCellStyle(cellStyle);
                    }
                }
            }
        }
    }

    对于一个excel多sheet, 操作也是一样

    // 不同的是这里可以定义多个监听器
    // readSheet(0)  —-> 这里的数据代表sheet的位置
    OltDrugFrequencyListener oltDrugFrequencyListener = new OltDrugFrequencyListener(isCfgPrd, dfCodeList, frequencyDto, oltConfigService);
    OltDrugUsageListener oltDrugUsageListener = new OltDrugUsageListener(isCfgPrd, dUCodeList, OltDrugUsageDto.builder().hosId(frequencyDto.getHosId()).build(), oltConfigService);
    OltDrugDurationListener oltDrugDurationListener = new OltDrugDurationListener(durationCodeList, OltDrugDurationDefDto.builder().hosId(frequencyDto.getHosId()).build(), oltConfigService);
    
    ReadSheet readSheet = EasyExcel.readSheet(0).registerReadListener(oltDrugFrequencyListener).build();
    ReadSheet readSheet2 = EasyExcel.readSheet(2).registerReadListener(oltDrugUsageListener).build();
    ReadSheet readSheet4 = EasyExcel.readSheet(4).registerReadListener(oltDrugDurationListener).build();
    excelReader.read(readSheet, readSheet2, readSheet4);

    经过测试, 该方法导出2W条数据差不多需要10秒, 也不会影响内存

    展开全文
  • 1.想把814G的json文件导入mongoDB中,抽取想要数据的三元组。(814G的json文件来自与wikidata中的数据) 2.或者怎么用json数据解析法抽取其中的三元组。 (问题难点都是数据太大内存不够,需要分批处理,怎么分批...
  • 上传CSV文件,并分批导入至数据库

    千次阅读 2018-01-15 12:01:00
    外部导入csv文件,将数据解析并插入到mysql数据库 2.项目环境 spring spring mvc mybatis 3.解决方法 (1) 上传并读取csv文件 /** * @TODO spring mvc 方式文件上传 * @param multipartFile * @param...

    1.需求场景

    外部导入csv文件,将数据解析并插入到mysql数据库

    2.项目环境

    spring spring mvc mybatis

    3.解决方法

    (1) 上传并读取csv文件

    	/**
    	 * @TODO spring mvc 方式文件上传
    	 * @param multipartFile
    	 * @param request
    	 * @return
    	 * @throws Exception
    	 */
    	public static String uploadFileCSV(MultipartFile multipartFile,
    			HttpServletRequest request, String realPath) throws Exception {
    		// String realPath =
    		// request.getSession().getServletContext().getRealPath(_path);
    		String newFileName = System.currentTimeMillis() + ".csv";
    
    		File path = new File(realPath);
    		if (!path.exists()) {
    			path.mkdirs();
    		}
    		String fileName = multipartFile.getOriginalFilename();
    		fileName = realPath + File.separator + newFileName;
    		File restore = new File(fileName);
    		multipartFile.transferTo(restore);
    		return newFileName;
    	}

    /**
    	 * 
    	 * @Title: readCSVFile
    	 * @Description: TODO 解析CSV文件  使用 javacsv.jar 解析
    	 * @param csvFilePath
    	 * @return
    	 * @throws IOException
    	 */
    	public static List<String[]> readCSVFile(String csvFilePath) {
    		List<String[]> csvList = new ArrayList<String[]>();
    		CsvReader reader = null;
    		try {
    			reader = new CsvReader(csvFilePath, ',', Charset.forName("UTF-8"));
    			 reader.readHeaders(); // 跳过表头   如果需要表头的话,不要写这句。  
    			while (reader.readRecord()) { // 逐行读入除表头的数据
    				csvList.add(reader.getValues());
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			if (reader != null) {
    				reader.close();
    			}
    		}
    		
    		
    		return csvList;
    	}
    public static boolean isCsv(String fileName) {
    		if (fileName.endsWith(".csv")) {
    			return true;
    		} else {
    			return false;
    		}
    	}



    (2)分批执行插入数据库

    /**
     *
     * TODO CSV文件上传导入到数据库
     * @param param
     *
     */
    @ResponseBody
    @RequestMapping("insertbatch")
    public ModelAndView insertBatch(@RequestParam(value = "file", required = false) MultipartFile file, HttpServletRequest request,String startDate, Model model) {  
    	final String username=(String) request.getSession().getAttribute("username");
    	String fileName="";
    	String filePath="";
    	String time = FormatTime.getDefaultTime();
    	startDate = EncodeUtil.checkParamEmpty(startDate, time);
    	if(FileUtil.isCsv(file.getOriginalFilename())){ //判断上次的文件是否是 .csv结尾
    		String path = request.getSession().getServletContext().getRealPath("upload/data");
    		try {
    			fileName =  FileUtil.uploadFileCSV(file,request,path);
    			filePath = path+File.separator+fileName;//上传文件的真实路径
    			List<String[]> dataFromCSV = FileUtil.readCSVFile(filePath);
    			final List<UploadBean> datalist =new ArrayList<UploadBean>();
    			if(dataFromCSV!=null && dataFromCSV.size()>0){
    				for (int i = 0; i < dataFromCSV.size(); i++) {
    					UploadBean b = new UploadBean();
    					    b.setPeriodcode(startDate);
    					    b.setId(str[0]);
    					    b.setPrice(str[1]);
    				      datalist.add(b);
    					} 
    				}
    				
    				//执行批量插入操作(耗时)
    		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();  
    	             cachedThreadPool.execute(new Runnable() {  
    	                 public void run() {  
    	                	 int len = 1000;
    	     				try{
    	     					if(datalist!=null && datalist.size()>0){
    	     						int totalSize = datalist.size(); //总记录数
         							int pageSize = len; //每页N条
         							int totalPage = totalSize/pageSize; //共N页
         							if (totalSize % pageSize != 0) {  
         								totalPage += 1;  
         								if (totalSize < pageSize) {  
         									pageSize = datalist.size(); 
         								}  
         							}  
         					System.out.println("循环保存的次数:"+totalPage);//循环多少次  
         					for (int pageNum = 1; pageNum < totalPage+1; pageNum++) {
         					int starNum = (pageNum-1)*pageSize;
         					int endNum = pageNum*pageSize>totalSize?(totalSize):pageNum*pageSize;
         					System.out.println("起始:"+starNum+"-"+endNum);
         					System.out.println("第"+pageNum+"批:");
         				service.insertBatch(datalist.subList(starNum, endNum));//上传文件数据插入 表
    
         							}
    	     					}
    	     				}catch(Exception e){
    	     					e.printStackTrace();
    	     						try {
    						EmailUtil.sendEmail("test@demo.com", "标题", "内容");
    								} catch (Exception e1) {
    									// TODO Auto-generated catch block
    									e1.printStackTrace();
    								}
    	     				}
    	     				 
    	                 }  
    	             });  
    	             cachedThreadPool.shutdown();  
    				
    				try{
    				 EmailUtil.sendEmail(filePath,"test@demo.com", "标题", "内容");
    				 }catch(Exception e){
    					 e.printStackTrace();
    					 model.addAttribute("message", "邮件发送失败");
    				 }
    				 model.addAttribute("message", "文件上传成功");
    			}
    		}catch(Exception e){
    		 e.printStackTrace();	
    		}
    	}
    	 return new ModelAndView(new MappingJacksonJsonView());
    }
    (3)Mybatis 批量入库配置

    <select id="insertBath"  resultType="java.lang.Integer">
    	 insert into  demo
                (id,price) 
            values 
            <foreach collection="list" item="item" index="index"
            separator=",">  
                (#{item.id},#{item.price})  
            </foreach>  
    	</select>


    展开全文
  • mysql分批导出数据和分批导入数据库  由于某些原因,比如说测试环境有很多库,需要迁移到新的环境中,不需要导出系统库的数据。而数据库又有好多,如何才能将每个库导出到独立的文件中呢?导入到一个文件的话,又...

    mysql分批导出数据和分批导入数据库

      由于某些原因,比如说测试环境有很多库,需要迁移到新的环境中,不需要导出系统库的数据。而数据库又有好多,如何才能将每个库导出到独立的文件中呢?导入到一个文件的话,又很大,不好办。

    这里是这个在测试环境下的实验记录,方便操作。

    # 导出的脚本

    #!/bin/bash
    
    #######################################################
    # Function: dump databases
    # Author: davie
    # Date: 2019-05-20
    # Version: 1.0
    # Script name: /usr/local/scripts/mutiple_database_dump.sh
    #######################################################
    
    Date_time=`date +%F_%H_%M`
    Host="192.168.100.100"
    User_name="admin"
    Pass_word="admin_password"
    Back_dir="/data/mysql/lww_dump/192.168.100.100_dump"
    Mysql_cmd="/usr/local/mysql/bin"
    
    if [ ! -d $"Back_dir"  ] ;then
        mkdir -p "${Back_dir}"
    fi
    
    "${Mysql_cmd}"/mysql -h "${Host}" -u"${User_name}" -p"${Pass_word}" -e "show databases"|grep -Evi 'Database|information_schema|mysql|performance_schema' | while read db;
    do
        echo "$db"
    "${Mysql_cmd}"/mysqldump -h "${Host}" -u"${User_name}" -p"${Pass_word}" --opt --hex-blob --default-character-set=utf8mb4 --skip-tz-utc --single-transaction --master-data=2 -B "${db}" | gzip> "${Back_dir}"/"${db}"."${Date_time}".sql.gz & done

     

    # 导入脚本

    # 导入脚本
    #!/bin/bash
    
    #######################################################
    # Function: import databases
    # Author: davie
    # Date: 2019-05-20
    # Version: 1.0
    # Script name: /usr/local/scripts/mutiple_database_import.sh
    #######################################################
    
    Date_time=`date +%F_%H_%M`
    Host="192.168.100.101"
    User_name="admin"
    Pass_word="admin_password"
    Back_dir="/data/mysql/lww_dump/192.168.100.100_dump"
    Mysql_cmd="/usr/local/mysql/bin"
    Log_file="/data/mysql/lww/lww_dump/logs"
    
    
    ls "${Back_dir}"  | while read dbfile;
    do
            /usr/bin/gunzip <"${Back_dir}"/"${dbfile}" | "${Mysql_cmd}"/mysql -h "${Host}" -u"${User_name}" -p"${Pass_word}"
            if [ $? -eq 0 ]; then 
                    echo "${Date_time}" >>"${Log_file}"/"${Host}".import.logs
                    echo ""${dbfile}" ok" >>"${Log_file}"/"${Host}".import.logs
            else    
                    echo "${Date_time}" >>"${Log_file}"/"${Host}".import.logs
                    echo ""${dbfile}" error" >>"${Log_file}"/"${Host}".import.logs
            fi 
    done

     

    转载于:https://www.cnblogs.com/bjx2020/p/10918758.html

    展开全文
  • 谁有数据分批导入excel 或者csv 文件的代码呢? 贴出来分享下。。。
    谁有数据分批导入excel 或者csv 文件的代码呢?
    贴出来分享下。。。
    展开全文
  • Dir分批导入Excel

    2018-01-05 16:21:08
    遠端磁盤文件夾寫法 #$Dir=Invoke-Command -ComputerName 10.148.55.49 -ScriptBlock {Get-ChildItem "C:\Users\Administrator\Desktop\PowerShell 脚本 " -Recurse -Force -Include *.*} -Credential "Wintel\...
  • 本篇文章主要介绍PHP读取CSV大文件导入数据库的方法,感兴趣的朋友参考下...为了成功将CSV文件里的数据导入数据库,分批处理是非常必要的。下面这个函数是读取CSV文件中指定的某几行数据:/*** csv_get_lines 读取CS...
  •  4、生成batch:将数据分批导入。 关于为什么要分批,笔者觉得分批不是看起来比较好嘛(其实因为穷,买不起好显卡),因为同时导入大量图像会导致内存消受不起,然后>>>:ResourceExhaustError... 第三步中...
  • 同时注意在配置文件下放入excel/*.xls文件 Created by ******** on 20160905 通读excel,由于excel的读取是按照字段读取,故需要设置边界量,表明已经到达边界 / public class ImportExcelUtil { private ...
  • 现有100-200个TXT数据文件,每个文件中存贮的数据量不尽相同,例如有的存储2~3万条,有的存贮2~3百条数据,现需要将这些文件导入到Sql Server数据库中;导入过程需在前台页面中显示出每个文件导入的基本情况(导入...
  • Python:将文件批量导入Excel文件

    千次阅读 2019-06-26 15:50:39
    #Date:2019-06-26 #Author:clfvita # -*- encoding: utf-8 -*- #若无此模块,先安装pip install xlwt(txt转表格) ...#将文件批量导入xls、xlsx表格(txt、out、csv等文件都可转化) def Txt_Xls(path,xlsname): ...
  • PHP中批量导入文件

    2013-08-28 15:54:10
    适用于PHP中批量导入文件到数据库中的表,而且是分批导入,效率更高。
  • 批量读取txt文件导入到数据库中,批量读取txt文件导入到数据库中 批量读取txt文件导入到数据库中,批量读取txt文件导入到数据库中
  • 为了成功将CSV文件里的数据导入数据库,分批处理是非常必要的。 下面这个函数是读取CSV文件中指定的某几行数据: /** * csv_get_lines 读取CSV文件中的某几行数据 * @param $csvfile csv文件路径 * @param $...
  • impdp导入dmp文件

    万次阅读 2017-03-09 12:49:32
    只能导入expdp导出的dmp文件。 expdp导出的时候,需要创建DIRECTORY 导出什么表空间,导入也要什么表空间。 导出什么用户,导入也要什么用户。 如果没有要新建。 从杭州服务器expdp导出了TOOLBOX用户的数据库dmp...
  • 本篇文章小编为大家介绍,基于PHP读取TXT文件向数据库导入海量数据的方法。需要的朋友参考下
  • 一、文件压缩与解压 sql文件比较大,通常会压缩至大概十分之一大小。 1、压缩文件 非打包 tar -czvf test.tar.gz test.sql //压缩 test.sql文件为test.tar.gz(会保留原文件) tar -czvf test.tar.gz test/ //压缩...
  • 当任务需求不同时,可以定制导入到Python中的数据,甚至当数据量过大时,还需要考虑分批导入或者转换数据类型以减少占用内存空间。 #导入pandas库 import pandas as pd import numpy as np from io import StringIO ...
  • 分割mysql 大sql文件批量导入

    千次阅读 2018-06-07 17:54:49
    其中-l 8000意思是以8000行为单位分割split --verbose -l 8000 st_2018-06-04_stock.sql -d -a 2 --additional-suffix=.sql split_st2、mkdir tempmv split*.sql temp3、创建batch.sh文件,内容如下 #!...
  • 采用ADO.NET将数据文件导入到MySQL数据库中,如果数据文件大于200M,在进行导入过程中,很容易出现内存不足的问题,因此对数据文件需要考虑分批加载到二进制字段中,在MySQL中有个CONCAT函数,可以用于实现将字段中...
  • excel文件导入数据库

    2019-09-30 17:21:29
    1、准备jar包:poi ...form表单中必须添加enctype="multipart/form-data"才可以上传文件 servlet中根据file名称来获取文件相对路径 --> <form action="/phoneQuery" method="post" encty...
  • PHP读取CSV大文件导入数据库

    千次阅读 2015-11-09 16:07:31
    为了成功将CSV文件里的数据导入数据库,分批处理是非常必要的。 下面这个函数是读取CSV文件中指定的某几行数据: /** * csv_get_lines 读取CSV文件中的某几行数据 * @param $csvfile csv文件路径
  • csv文件导入导出

    2019-08-30 15:04:23
    导出: String str = DateFormatUtils.format(new Date(), ...String csvFileName = "导出文件" + str + ".csv"; response.setContentType("text/csv;charset=utf-8"); String headerKey = "Content-Disp...
  • 数据迁移和数据导入是两个不同的概念:数据迁移指的是数据从数据库到数据库,数据导入指的是数据从数据文件(txt、csv等)到数据库。严格来讲实际上数据迁移包含了数据导入。 1数据导入 数据导入 1.1CSV文件导入 ...
  • 当dmp文件是oracle11G导出来,你本机的客户端oracle为10G时,导入数据库不会成功。 原因:高版本的数据库文件无法向下兼容。 解决方法:用Madedit编辑器打开dmp文件,把dmp头部关于数据库版本的信息改为你本...
  • 本文章来给各位朋友介绍利用mysql source命令超大文件导入方法总结,下面收集了两种解决办法,一种是把数据库分文件导出然后再导入,另一种是修改my.ini配置文件,下面我一一给各位朋友介绍。 导入1G的数据,但是在...
  • 今天做了一个基于SQL Server的文本文件批量导入工具,和大家分享一下心得。  方案一: 遍历文本文件,解析每一行,形成SQL语句后向数据库插入。 方案二 遍历文本文件,解析每一行,将SQL语句保存到文本文件然后执行...
  • 为了成功将CSV文件里的数据导入数据库,分批处理是非常必要的。 下面这个函数是读取CSV文件中指定的某几行数据: /** * csv_get_lines 读取CSV文件中的某几行数据 * @param $csvfile csv文件路径 * @param...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,744
精华内容 1,497
关键字:

文件分批导入