vue+springboot으로 excel 파일 다운로드 및 업로드

9936 단어
CSDN 링크:https://blog.csdn.net/sinat_27537929/article/details/98059599

수요

  • 전방에서 다운로드 요청을 발송합니다
  • 백엔드에서 요청을 받고 데이터베이스에서 데이터를 꺼내 excel 형식으로 작성하여 백엔드에 전달합니다
  • 전단에서 excel을 받아 다운로드합니다
  • excel에서 데이터를 추가합니다
  • 새로운 excel을 서버에 업로드합니다

  • 환경

  • 프런트엔드 vue+ElementUI
  • 백엔드springboot+mybatisplus+mysql
  • 백엔드에서 excel을 생성하여 org에 사용합니다.apache.poi

  • 다운로드


    html
     
    

    js
        exportWord () {
          this.$axios.post('/web/xxxxxx/export', {}, {
            responseType: 'blob'
          }).then(res => {
            let blob = new Blob([res.data], { type: 'application/ms-excel;charset=utf-8' });
            let downloadElement = document.createElement('a');
            let href = window.URL.createObjectURL(blob); // 
            downloadElement.href = href;
            downloadElement.download = 'forbidden-words.xls'; // 
            document.body.appendChild(downloadElement);
            downloadElement.click(); // 
            document.body.removeChild(downloadElement); // 
            window.URL.revokeObjectURL(href); // blob 
          })
        }
    

    controller
        @PostMapping("/export")
        public void exportXXXXXXWords(HttpServletResponse response) {
            List forbiddenList;
            try {
                // get your data
                wordList = wordService.getWords();
                //  excel 
                String[] titleRow = new String[]{" ", " "};
                List data = new LinkedList();
                data.add(0, titleRow);
                for (int i = 0; i < wordList.size(); i++) {
                    Word word = wordList.get(i);
                    data.add(new String[]{
                            word.getWord(),
                            word.getLevel().toString()
                    });
                }
                Map> exportData = new HashMap>();
                //  sheet 
                exportData.put("Your sheet name", data);
                String strResult = FileUtils.createExcelFile(response, exportData);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    FileUtils
        /**
         *  
         *
         * @param response
         * @param exportData
         * @return
         */
        public static String createExcelFile(HttpServletResponse response, Map> exportData) {
            OutputStream outputStream = null;
            try {
                Workbook wb = new HSSFWorkbook();
    
                for (String sheetName : exportData.keySet()) {
                    Sheet sheet = wb.createSheet(sheetName);
                    List rowData = exportData.get(sheetName);
                    for (int i = 0; i < rowData.size(); i++) {
                        String[] cellData = rowData.get(i);
                        Row row = sheet.createRow(i);
                        for (int j = 0; j < cellData.length; j++) {
                            Cell cell = row.createCell(j);
                            cell.setCellValue(cellData[j]);
                        }
                    }
                }
                response.setContentType("application/vnd.ms-excel;charset=utf-8");
                response.flushBuffer();
                outputStream = response.getOutputStream();
                wb.write(outputStream);
            } catch (IOException ex) {
                ex.printStackTrace();
                return "failure";
            } finally {
                try {
                    if (outputStream != null) {
                        outputStream.flush();
                        outputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return "success";
        }
    

    업로드


    우선, 회사는axios를 봉인하여 발송할 때마다 token 등의 데이터를 가지고 있어야 하기 때문에 ElementUI에서el-upload 구성 요소의 action을 직접 사용할 수 없습니다.el-upload에는 http-request가 있습니다. 기본적인 업로드 행위를 덮어쓰고 업로드를 사용자 정의할 수 있습니다. 수신 형식은function입니다. 바로 그입니다.여기에서 저는 auto-upload='false'라는 속성을 사용했습니다. 즉,'파일을 선택한 후에 바로 업로드할지 여부'를 선택하면 바로 업로드하지 않기 때문에 터치 업로드를 실현하기 위해 단추를 하나 더 추가했습니다.
    html
        
             
             
          
    

    js
        submitUpload () {
          this.$refs.upload.submit();
        },
        importWordConfirm (item) {
          const fileObj = item.file
          const formData = new FormData()
          formData.append('file', fileObj)
          this.$axios.post('/web/xxxxxx/import', formData, {
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          }).then(res => {
            // do something
          })
        }
    

    controller
        @PostMapping("/import")
        public ApiResult importXXXXXXWords(
                @RequestParam("file") MultipartFile uploadFile,
                HttpServletRequest request) throws Exception {
            try {
                if (uploadFile == null) {
                    // 
                    return failure("-1", " ");
                }
                
                //  
                //  
                // Constant.UPLOAD_DIRECTORY 
                String uploadPath = request.getServletContext().getRealPath("/")
                        + File.separator + Constant.UPLOAD_DIRECTORY;
    
                // 
                File uploadDir = new File(uploadPath);
                if (!uploadDir.exists()) {
                    uploadDir.mkdir();
                }
    
                String fileName = uploadFile.getOriginalFilename();
                String originalFileName = fileName
                        .substring(0, fileName.lastIndexOf("."));
                // 
                String suffix = fileName
                        .substring(fileName.lastIndexOf("."));
                String newFileName = originalFileName
                        + "_" + UUID.randomUUID().toString() + suffix;
    
                File file = new File(uploadPath, newFileName);
                try {
                    uploadFile.transferTo(file);
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
                List fileData = null;
                if (suffix.equals(".xls")) {
                    fileData = FileUtils.readXlsFile(file.getAbsolutePath());
                } else if (suffix.equals(".xlsx")) {
                    fileData = FileUtils.readXlsxFile(file.getAbsolutePath());
                } else {
                    return failure("-2", " ");
                }
    
                // do something
    
                return success(" ");
            } catch (Exception e) {
                e.printStackTrace();
                return failure("-1", " ");
            }
        }
    

    FileUtils
        public static List readXlsFile(String filePath) {
            HSSFWorkbook workbook = null;
            List list = new LinkedList();
            try {
                workbook = new HSSFWorkbook(new FileInputStream(filePath));
                HSSFSheet sheet = workbook.getSheetAt(0);
                int rowNumber = sheet.getLastRowNum();
                for (int i = 0; i < rowNumber + 1; i++) {
                    HSSFRow row = sheet.getRow(i);
                    int lastCellNum = row.getLastCellNum();
                    String[] cells = new String[lastCellNum];
                    for (int j = 0; j < lastCellNum; j++) {
                        HSSFCell cell = row.getCell(j);
                        if (cell != null) {
                            cells[j] = cell.toString();
                        } else {
                            cells[j] = "";
                        }
                    }
                    list.add(cells);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 
            list.remove(0);
            return list;
        }
    
        public static List readXlsxFile(String filePath) {
            XSSFWorkbook workbook = null;
            List list = new LinkedList();
            try {
                workbook = new XSSFWorkbook(new FileInputStream(filePath));
                XSSFSheet sheet = workbook.getSheetAt(0);
                int rowNumber = sheet.getLastRowNum();
                for (int i = 0; i < rowNumber + 1; i++) {
                    XSSFRow row = sheet.getRow(i);
                    int lastCellNum = row.getLastCellNum();
                    String[] cells = new String[lastCellNum + 1];
                    for (int j = 0; j < lastCellNum; j++) {
                        XSSFCell cell = row.getCell(j);
                        cells[j] = cell.toString();
                    }
                    list.add(cells);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 
            list.remove(0);
            return list;
        }
    

    여기에 또 두 가지 에피소드를...
  • 그때 콘솔을 생각했어요.log(formData), 결과적으로 console의 결과가 {}인 것을 발견했습니다. 데이터가 없는 줄 알았는데...나중에 다른 사람의 글을 보니 이렇게 써야 한다는 것을 알게 되었다. 콘솔.log(formData.get('xxx'))
  • 회사가 axios를 봉인했기 때문에 매번post를 할 때마다 나는 그다지 옳지 않다는 것을 발견했다.원래 회사가 설정한 httprequest 차단기는 기본적으로post의 Content-Type을'application/x-www-form-urlencoded로 변경합니다.charset=UTF-8'...그런데'Content-Type':'multipart/form-data'가 필요해요!!!그리고 묵묵히 차단기에 판단을 했는데..

  • 참조:


    ElementUI의 upload 구성 요소를 사용하여 Excel 파일 업로드 vue 프로젝트에서 다운로드 백엔드에서 되돌아오는 excel 데이터 표를 실행합니다. Spring boot는 데이터를 내보내서 excel 파일을 생성합니다.

    좋은 웹페이지 즐겨찾기