找回密码
 立即注册

QQ登录

只需一步,快速开始

ann 悬赏达人认证

初级会员

4

主题

148

帖子

356

积分

初级会员

积分
356

悬赏达人

最新发帖
ann 悬赏达人认证
初级会员   /  发表于:2022-8-25 11:58  /   查看:2240  /  回复:1
本帖最后由 ann 于 2022-8-25 12:04 编辑

日常向开发中,如果是前后端分离的项目,同时涉及到文件的操作,难免存在文件传输的需求,本质上是对文件流的传输和解析,下面我们通过代码实战来直观感受下。

一、前端同步文件到后端SpreadJs在保存文件时,借助GC.Spread.Excel.IO组件的save方法,可以获取到文件的blob对象。因此在前端项目中可通过调用save方法,获取到blob对象,然后重写自己的文件传输逻辑。

SpreadJs导入导出Excel官网实例:https://demo.grapecity.com.cn/sp ... mport-export/purejs
Blob对象简介:BLOB 简介

1.1 前端实现-React前端借助SpreadJs的在线表格编辑器,导入本地Excel文件,借助excelIo.save方法获取到文件的Blob对象,然后以表单的方式提交请求到后端。
前端代码
  1. import React from 'react'
  2. import {Button, Col, message, Space, Switch} from "antd";
  3. import '@grapecity/spread-sheets-resources-zh';
  4. import '@grapecity/spread-sheets-designer-resources-cn';
  5. import {Designer} from '@grapecity/spread-sheets-designer-react';
  6. import GC from "@grapecity/spread-sheets";
  7. import * as ExcelIo from "@grapecity/spread-excelio"

  8. GC.Spread.Common.CultureManager.culture("zh-cn");
  9. const config = GC.Spread.Sheets.Designer.DefaultConfig

  10. export default class SpreadJs extends React.Component {
  11.     constructor(props) {
  12.         super(props);
  13.         this.designer = null
  14.         this.state = {
  15.             spread: null,
  16.         }
  17.     }

  18.     componentDidMount() {

  19.     }

  20.     onClick = () => {
  21.         let spread = this.state.spread;
  22.         let json = spread.toJSON();
  23.         this.excelIo = new ExcelIo.IO();
  24.         this.excelIo.save(json, function (blob) {
  25.             let formData = new FormData();
  26.             formData.append("content", blob,"111.xlsx");
  27.             let request = new XMLHttpRequest();
  28.             request.open("POST", "http://localhost:8080/send/file/blob",)
  29.             request.send(formData)
  30.         }, function (e) {
  31.             console.log(e);
  32.         });
  33.         //也可直接将string对象转换为Blob然后传输到后端
  34.         //let blob=new Blob([JSON.stringfy(spread.toJSON())],{type:"application/json"})
  35.     }

  36.     /**
  37.      * 初始化spread
  38.      * @param designer
  39.      */
  40.     designerInitialized = (designer) => {
  41.         this.designer = designer;
  42.         let spread = this.designer.getWorkbook()
  43.         this.setState({spread})
  44.     }

  45.     render() {
  46.         return (
  47.             <div>
  48.                 <Col>
  49.                     <Button type='primary' onClick={this.onClick}
  50.                             style={{backgroundColor: '#22e7ff', marginLeft: 20, marginTop: 5}}>向后端传输文件</Button>
  51.                 </Col>
  52.                 <Designer
  53.                     spreadOptions={{sheetCount: 1}}
  54.                     styleInfo={{width: "100%", height: '80vh'}}
  55.                     config={config}
  56.                     designerInitialized={this.designerInitialized}
  57.                 ></Designer>
  58.             </div>
  59.         )
  60.     }
  61. }
复制代码
1.2 后端实现-JAVA
  1. @RequestMapping(value = "/send/file/blob", produces = {"application/json;charset=utf-8"})
  2. public void sendFileBlob(HttpServletResponse response, HttpServletRequest request) {
  3.     MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
  4.     Iterator<String> iter = multiRequest.getFileNames();
  5.     while (iter.hasNext()) {
  6.         MultipartFile multipartFile = multiRequest.getFile(iter.next());
  7.         if (null != multipartFile) {
  8.             String fileName = multipartFile.getOriginalFilename();
  9.             if (fileName == null || fileName.trim().equals("")) {
  10.                 continue;
  11.             }
  12.            //todo 具体的业务逻辑
  13.         }
  14.     }
  15. }
复制代码
1.3 效果演示
借助SpreadJs的在线表格编辑器,导入本地文档111.xlsx。

点击“向后端传输文件”按钮,触发文件传输,后端可获取到对应的文件信息。可做具体的业务逻辑。


二、后端同步文件到前端
从后端后获取文件流同步到前端,然后直接在浏览器中下载
2.1 前端实现-React
  1. //加载指定的文件流到前端浏览器下载
  2. loadFile = () => {
  3.     let filePath = "/Users/yak/myProject/exceldemo/tttt3.xlsx";
  4.     return new Promise((resolve, reject) => {
  5.         axios({
  6.             method: 'get',
  7.             url: "http://localhost:8080/upload/file?filePath=" + filePath,
  8.             responseType: 'blob'
  9.         }).then(data => {
  10.             let blob = data.data;
  11.             const link = document.createElement("a");
  12.             link.href = URL.createObjectURL(blob);
  13.             link.download = "text.xlsx";
  14.             link.click();
  15.             link.remove();
  16.             URL.revokeObjectURL(link.href);}).catch(error => {
  17.             reject(error.toString())
  18.         })
  19.     })
  20. }
复制代码
2.2 后端实现-JAVA
读取本地文件,将其转换为二进制字节流,提供接口给第三方访问。
  1. @GetMapping(value = "/upload/file")
  2. public void download(String filePath, HttpServletResponse response) throws Exception {
  3.     ServletOutputStream out = null;
  4.     ByteArrayOutputStream byteArrayOutputStream = null;
  5.     try {
  6.         FileInputStream inputStream = new FileInputStream(filePath);
  7.         String[] filePaths = StringUtil.split(filePath,"/");
  8.         byte[] buffer = new byte[1024];
  9.         int len;
  10.         byteArrayOutputStream = new ByteArrayOutputStream();
  11.         while ((len = inputStream.read(buffer)) != -1) {
  12.             byteArrayOutputStream.write(buffer, 0, len);
  13.         }
  14.         response.addHeader("Content-Disposition", "attachment;filename=" + filePaths[filePaths.length-1]);
  15.         response.addHeader("Content-Length", "" + byteArrayOutputStream.size());
  16.         response.setHeader("filename", filePaths[filePaths.length-1]);
  17.         response.setContentType("application/octet-stream");
  18.         out = response.getOutputStream();
  19.          out.write(byteArrayOutputStream.toByteArray());
  20.     } catch (Exception e) {
  21.         e.printStackTrace();
  22.         throw new RuntimeException();
  23.     } finally {
  24.         // 关闭文件流
  25.         if (null != byteArrayOutputStream) {
  26.             byteArrayOutputStream.flush();
  27.             byteArrayOutputStream.close();
  28.         }
  29.         if (null != out) {
  30.             out.flush();
  31.             out.close();
  32.         }
  33.     }
  34. }
复制代码
2.3 效果演示
前端获取到后端同步的文件流对象

浏览器侧的下载实现















image.png289706420.png
image.png475663756.png
image.png610864257.png
image.png516631774.png
image.png366204222.png

1 个回复

倒序浏览
Derrick.Jiao讲师达人认证 悬赏达人认证 SpreadJS 开发认证
论坛元老   /  发表于:2022-8-25 13:39:03
沙发
求完整demo
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部