react-前端excel 文件/PDF文件 导入 --导出,照片上传

news2024/11/19 1:32:56

需要了解,new FormData() --上传时,将内容转为文件流

                 new FileReader()--base64压缩,目前不了解

一、excel文件导出

     三种导出: 一种是纯粹前端导出;两种后端导出: 分为 后端给地址导出,还有就是文件流的形式导出,最好是后端导出,不会卡 ,前端导出数据量一大 很卡

    Blod:blob是存放二进制大对象的容器,包括large object ;创建一个bold对象

    后端返回二进制数据流,生成Excel : 

    ① 点击模板获取--导出,弹框进行确认,点击确认

    ② 调接口,获取结果,接口的reaponseType: ' blob'

    ③ 调用window的url方法,创建a标签,点击a = url, 设置点击下载

  -- 导出文件为 pdf 时,修改 type: 'application/pdf;chartset=UTF-8' 

  // 模板获取

  const getTemplate = async () => {
    const res = await getStuTemplate()
    // const blob = new Blob(['\ufeff' + res], { type: 'application/vnd.ms-excel' })

    // 调用window的url方法
    const url = window.URL.createObjectURL(res)

    // 通过创建a标签实现
    const link = document.createElement('a')
    link.href = url

    // 命名
    // link.download = res?.headers['content-disposition'].split(';')[1].split('=')[1] || '模板'
    link.download = decodeURI('考生信息')
    document.body.appendChild(link)

    // 下载文件
    link.click()

    // 释放内存 
    document.body.removeChild(link)
  }
// 考生信息--导出excel模板
export async function getStuTemplate(params?: any) {
  return request(`/${Proxy_Api}/entrantManage/exportExcel`, {
    method: 'GET',
    responseType: 'blob',
    params,
  })
}
// 导出 -- PDF
  const getTemplate = async () => {
    const res = await getStuTemplate({ code })
     // 创建blob对象,解析流数据
    const blob = new Blob([res], { type: 'application/pdf;chartset=UTF-8'})
    // 调用window的url方法,根据解析后的blob对象创建URL 对象
    const url = window.URL.createObjectURL(blob)
    // 通过创建a标签实现
    const link = document.createElement('a')
    link.href = url
    // 命名
    // link.download = res?.headers['content-disposition'].split(';')[1].split('=')[1] || '模板'
      link.download = decodeURI('请假统计')
      document.body.appendChild(link)
      // 下载文件
      link.click()
      // 释放内存 
      document.body.removeChild(link)
  }

二、excel文件 导入--上传

   ① 用Dragger组件进行上传,点击上传后,选取文件

   ② 设置组件的props,用beforeUpload钩子函数拦截文件,不设置action地址,取消自动上传

   ③ 通过beforeUpload,拦截默认上传,对上传文件进行处理,可以判断文件格式

   ④ 点击modal弹框的确认后,创建new FormData(),使用append,发送fetch请求,返回数据需要转化为json格式

① 设置组件

<Modal destroyOnClose={true} title="数据导入" visible={isUploadOpen} onOk={handleOkUpload} onCancel={handleCancelUpload} width={550}>
        <Dragger {...props} style={{ marginBottom: 20, marginTop: 20 }}>
          <p className="ant-upload-drag-icon"><InboxOutlined /></p>
          <p className="ant-upload-text">点击或将文件拖拽到这里上传</p>
          <p className="ant-upload-hint">当前仅支持扩展名:.xls/.xlsx</p>
        </Dragger>
        <p style={{ fontSize: 12, color: '#00000073', marginTop: 10 }}>注:若在此之前已经上传过数据而此次上传存在覆盖操作,则相关分组信息需要重新导入</p>
      </Modal>

// dragger组件
② 设置组件props

// 设置文件变量
 const [oneFile, setOneFile] = useState<any>();
 const props: UploadProps = {
    maxCount: 1, //最大数量
    multiple: false,  //是否支持多选
    onRemove: (file) => {  //删除
      setOneFile(null)
    },

    // beforeUpload 拦截默认上传,回调参数就是file文件
    // 可以对文件类型进行判断
    beforeUpload: (file) => {
      const fileName = file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length)
      const fileType = fileName == 'xls' || fileName == 'xlsx'
      if (!fileType) {
        message.error('上传失败,请上传xls/xlsx格式的文件')
      } else {
        setOneFile(file)
      }
      return false;
    },
  };
③ 上传文件

/**点击上传 */
  const handleOkUpload = () => {

    const formData = new FormData();
   
    formData.append('file', oneFile as RcFile);

    fetch(`${Proxy_Api}/entrantManage/importExcel/${code}`, {
      method: 'POST',
      body: formData,
    })
      .then((res) => {
        return res.json()
      })
      .then((res) => {
        if (res?.success) {
          message.success('导入成功');
          setOneFile(null)
          setIsUploadOpen(false)
        } else {
          message.error(res.desc)
        }
      })
      .catch(() => {
        message.error('导入失败');
      })
  };

三、照片上传

        ① 上传props,不设置action,设置beforeUpload,拦截上传文件

        ② 对上传文件进行判断,格式,大小,每次上传前,修改变量  oneFile ,用于最后提交

        ③ 设置props的 onChange,改变上传文件时,调用base64方法,修改imageUrl变量,用于在页面显示当前上传图片

        ④ 提交,new FormData 来转为文件流,使用append,发送fetch请求,返回数据需要转化为json格式

① 设置组件

const [imageUrl, setImageUrl] = useState<any>();

 <Form.Item label="考点图片" name="photo">

    <Upload  {...props} >

        {imageUrl ? 

        // 上传图片后,图片反显,图片+上传按钮

        [<img src={imageUrl} alt="avatar" style={{ height: '60px', marginRight: 10 }} />, <Button icon={<UploadOutlined />}>上传文件</Button>] 

        : <Button icon={<UploadOutlined />}>上传文件</Button>}</Upload>

 </Form.Item>
② 设置上传props

// 上传的props
const props: UploadProps = {
    maxCount: 1,
    multiple: false,
    name: "avatar",
    action: "#",
    listType: "picture",
    className: "avatar-uploader",
    showUploadList: false,
    onRemove: (file) => {
      setOneFile(null)
    },

    /**上传文件之前的钩子,参数为上传的文件,可设置文件格式和大小,若返回false停止上传 */
    beforeUpload: beforeUpload,
    onChange: handleChange,
  };
③ 提交上传文件

const [oneFile, setOneFile] = useState<any>(); //文件变量
/**上传文件之前的钩子,参数为上传的文件,可设置文件格式和大小,若返回false停止上传 */
  const beforeUpload = (file: RcFile) => {
    
    const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
    if (!isJpgOrPng) {
      message.error('请上传 JPG/PNG 格式的图片!');
    }
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isLt2M) {
      message.error('图片需要小于 2MB!');
    }
    setOneFile(file)
    return isJpgOrPng && isLt2M;
    // 返回false ,不请求,但是获取不到显示图片,用action:"#",替换不请求
    // return false;
  };
  ④ base64设置反显图片

  // 上传判断,是否显示图片
  const getBase64 = (img: RcFile, callback: (url: string) => void) => {
    const reader = new FileReader();
    reader.addEventListener('load', () => callback(reader.result as string));
    // 方法可以将读取到的文件编码成DataURL ,可以将资料(例如图片、excel文件)内嵌在网页之中,不用放到外部文件
    reader.readAsDataURL(img);
  };
  ⑤ onChange--上传文件改变时的回调 */

  const handleChange: UploadProps['onChange'] = (info: UploadChangeParam<UploadFile>) => {

    if (info.file.status === 'uploading') {
      return;
    }

    if (info.file.status === 'done') {
      getBase64(info.file.originFileObj as RcFile, (url) => {
        setImageUrl(url);
      });
    }
  };
⑥ 提交

/**新增、修改--确认 */
  const handleOk = () => {
    addForm.validateFields().then(async (values) => {
        if (imageUrl) {
          const { address, examYear, code, name } = values

          let newForm = new FormData()

          newForm.append("address", address);
          newForm.append("examYear", examYear);
          newForm.append('code', code);
          newForm.append('name', name);
          newForm.append('photo', oneFile);

            fetch(`${Proxy_Api}/examPlaceManage`, {
              method: 'POST',
              body: newForm,
            })
              .then((res) => {
                return res.json()
              })
              .then((res) => {
                if (res?.success) {
                  message.success('新增成功');
                  setOneFile(null)
                  setIsModalOpen(false);
                } else {
                  const { desc } = res
                  message.error(desc);
                }
              })
              .catch(() => {
                message.error('新增失败');
              })
         

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/409348.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

攻防世界web新手 - very_easy_sql(非常详细的wp)

文章目录攻防世界web新手XCTF - very_easy_sql知识点解题思路ssrf发现ssrf详解什么是ssrfssrf的利用产生SSRF漏洞的函数ssrf漏洞利用gopher协议报错注入查数据库查表查列名查内容分割读取攻防世界web新手XCTF - very_easy_sql 题目知识点确实很多&#xff0c;我想我这个wp大概…

【Vue全家桶】Vuex状态管理

&#x1f373;作者&#xff1a;贤蛋大眼萌&#xff0c;一名很普通但不想普通的程序媛\color{#FF0000}{贤蛋 大眼萌 &#xff0c;一名很普通但不想普通的程序媛}贤蛋大眼萌&#xff0c;一名很普通但不想普通的程序媛&#x1f933; &#x1f64a;语录&#xff1a;多一些不为什么的…

windows10下安装和配置nodejs环境

一、下载安装node.js 官方下载地址:下载最新LTS windows版本: 16.15.0 (includes npm 8.5.5) Node.js ,如下图安装可以更改安装路径(我的是默认地址C:\Program Files\) 其余的都是选择 下一步, 安装 测试是否安装 成功 打开开始菜单中输入cmd&#xff0c;打开cmd命令窗口&a…

微信小程序实现客服功能(客服消息)

纯前端操作&#xff0c;无后端接入的情况下实现此功能 1&#xff0c;需要一个按钮button&#xff0c;加上open-type“contact”属性 <button open-type"contact">咨询</button> 需在真机上测试&#xff0c;点击按钮就可以进入客服页面。 2&#xff0c…

猿创征文|前端之行,任重道远(来自大三学长的万字自述)

&#x1f9d1;‍&#x1f4bc;个人简介&#xff1a;本科大三学生、全栈领域优质创作者、华为云享专家、阿里云专家博主、第十三届蓝桥杯国赛三等奖获得者&#xff0c;拥有软件著作权1项。一个不甘平庸的平凡人&#x1f36c; &#x1f4d6; 前言 目前正值开学季&#xff0c;很多…

HTML系列之多媒体视频标签 video

文章の目录1、video 是什么了2、video的相关属性2.1、autoplay2.2、buffered2.3、controls2.4、loop2.5、muted2.6、height2.7、width2.8、preload2.9、src2.10、poster2.11、controlslist2.12、crossorigin2.13、currentTime2.14、disablePictureInPicture2.15、disableRemote…

web前端-JavaScript中的函数(创建,参数,返回值,方法,函数作用域,立即执行函数)

&#x1f41a;作者简介&#xff1a;苏凉&#xff08;专注于网络爬虫&#xff0c;数据分析&#xff0c;正在学习前端的路上&#xff09; &#x1f433;博客主页&#xff1a;苏凉.py的博客 &#x1f310;系列专栏&#xff1a;web前端基础教程 &#x1f451;名言警句&#xff1a;海…

VsCode安装yarn:yarn : 无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名

1.出现的问题&#xff1a; 在使用VSCode终端的时候&#xff0c;输入命令&#xff1a;yarn install &#xff0c;出现了问题: yarn : 无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&…

Less预处理——变量和嵌套

系列文章目录 文章目录系列文章目录一、Less 变量1、选择器变量2、属性变量3、url 变量4、声明变量5、变量运算6、变量的作用域7、用变量去定义变量二、Less 嵌套1、& 的使用2、媒体查询3、小技巧&#xff1a;添加私有样式一、Less 变量 1、选择器变量 让选择器变成动态的…

ant design vue的table取消自带分页

在我们使用ant design vue的table组件的时候会发现&#xff1a; 组件使用如示&#xff1a; <a-table :columns"columns" :data-source"data" bordered></a-table> 显然并没有配置pagination属性&#xff0c;那为什么会出现分页器呢&#xff1…

Three.js基础入门系列(一)

01 Three.js前提须知 讲到 Three.js&#xff0c;就需要先说一下 OpenGL 和 WebGL。 OpenGL 是一个跨平台的3D/2D的绘图标准&#xff08;规范&#xff09;&#xff0c;WebGL&#xff08;Web Graphics Library&#xff09;是一种3D绘图协议。 WebGL允许把JavaScript和OpenGL 结…

uniapp 开发安卓App实现高德地图路线规划导航

文章目录技术概述技术详述问题与解决我的总结参考文献技术概述 描述这个技术是做什么的/什么情况下会使用到这个技术&#xff0c;学习该技术的原因&#xff0c;技术的难点在哪里。控制在50-100字内。 uniapp的map组件中导航路线的展示。是uniapp开发app时引入地图导航的实现方…

21个超实用的 CSS 技巧分享(附图示)

本文中分享的所有CSS技巧都是来自GitHub代码库“css tips tricks”的手工精选&#xff0c;此代码库专为开发者提供专业的CSS技巧。1、文档布局使用仅两行CSS代码&#xff0c;创建一个响应式的文档布局。这个布局风格类似于文档页面&#xff0c;可以很好地展示各种信息。.parent…

【JavaScript】基于querySelector / querySelectorAll对元素的操作,为你的DOM API基础扫盲~

目录 一、通过querySelector / querySelectorAll获取元素 1.1 单个标签选中 1.2 多个标签选中 二、基于这组DOM API&#xff0c;对元素进行操作 2.1 innerHTML获取/修改元素内容 2.2获取/修改元素属性 三、单标签元素属性的获取和修改 3.1 value 3.2checked 3.3 type …

网上蛋糕商城JSP页面

首先是一个注册页面&#xff1a; 视图如下&#xff1a; 代码如下&#xff1a; <!DOCTYPE html> <html> <head><title>用户注册</title><meta name"viewport" content"widthdevice-width, initial-scale1"><meta …

前端案例:像素鸟小游戏(js+dom操作,完整代码,附案例素材)

目录 一、案例效果 二、实现思路 三、完整代码详细注释 四、案例素材 一、案例效果 二、实现思路 创建游戏背景板和小鸟&#xff0c;并分别设置相对定位与绝对定位&#xff1b;初始化背景图的位置&#xff1b;初始化小鸟的位置&#xff1b;设置游戏状态&#xff0c;游戏开…

vue 的表单验证

1.使用<el-form>包裹整个表单 在其中使用:model 绑定数据 和 :rules绑定校验规则 <el-form :model"user" :rules"rules"> ...................................... </el-from> 2.在script中添加使用数据 以及 校验规则&#xff08;都添加…

Chrome浏览器中清除特定网站的Cookie数据

背景&#xff1a;当我们在网站上遇到错误时&#xff0c;经常会用到的一个方法就是清除Cookie&#xff0c;清除网站的Cookie和网站数据来重置本地的缓存&#xff0c;很多客户端引起的错误都可以使用该方法修复&#xff0c; 但是在清除Cookie时有一个问题是使用浏览器更多中的清…

css实现文字大小自适应

在页面编写中经常会碰到页面自适应的问题&#xff0c;也就是页面内部的元素会随着窗口的放大缩小而放大缩小&#xff0c;box可以通过calc 百分比的形式做到页面自适应&#xff0c;但是box内的字体却无法做到这点&#xff0c;往往box自适应大小了&#xff0c;内部的字体还是原来…

一行代码“黑”掉任意网站

文章目录只需一行代码&#xff0c;轻轻一点就可以把任意网站变成暗黑模式。 首先我们先做一个实验&#xff0c;在任意网站中&#xff0c;打开浏览器开发者工具(F12)&#xff0c;在 C1onsole 控制台输入如下代码并回车&#xff1a; document.documentElement.style.filterinve…