react的pdf转图片格式上传到后端

这个东西做的我真的是头昏脑涨

主要需求是,upload上传pdf,pdf转图片格式展示,以图片格式上传到后端

封装了组件代码

父组件直接放就可以了

 使用的插件pdfjs-dist,版本是  "pdfjs-dist": "2.5.207",

import React, { useState, useEffect, useRef } from 'react';
import { Spin, Pagination } from 'antd';
import { Form, UploadProps, Image } from "antd";
import { message, Modal, Upload, Button } from "antd";
import { useDispatch, useSelector } from 'react-redux';
import type RootState from '@/types/rootState';
import { getToken } from "@/utils/login";
import config from "@/utils/config";
import type { RcFile, UploadChangeParam } from "antd/lib/upload";
import type { UploadFile } from "antd/es/upload/interface";
import { Toast } from "antd-mobile";
import { LoadingOutlined, PlusOutlined } from "@ant-design/icons";
import type { PurchaseOrderAction } from "@/pages/purchase/purchaseOrder/model";
var pdfjsLib = require('pdfjs-dist/build/pdf.js');
import 'pdfjs-dist/build/pdf.worker.entry';interface PdfViewerProps {url: string;
}
const formItemLayout = {labelCol: {span: 3,},wrapperCol: {span: 12,},
};
const PdfViewer = () => {const [pageNumbers, setPageNumbers] = useState(1);const [loading, setLoading] = useState(true);const [supportImages, setSupportImages] = useState<string[]>([]);const [uploadingImages, setUploadingImages] = useState<boolean>(false);const [supportFileList, setSupportFileList] = useState<UploadFile[]>([]);const [previewImage, setPreviewImage] = useState<string>('');const [previewVisible, setPreviewVisible] = useState<boolean>(false);const dispatch = useDispatch();const pdfRef: any = useRef(null);const processPage = async (pageNumbers: any, pdfFile: any, pdfName: any, uid: any, type: any) => {//  转base64let canvas: any = document.getElementById('pdf');let canvasContext = canvas.getContext('2d');const page = await pdfFile.getPage(pageNumbers);const viewport = page.getViewport({ scale: 5 });canvas.height = viewport.height;canvas.width = viewport.width;canvasContext.clearRect(0, 0, canvas.width, canvas.height);const renderContext = {canvasContext: canvasContext,viewport: viewport,rotate: 90,};await page.render(renderContext).promise;// 转base64const imgUrl = canvas.toDataURL('image/jpg');const thumbimg = dataURLtoFile(imgUrl, 'image/png');const fileOfBlob = new File([thumbimg], `${pdfName}.png`);const formData = new FormData();formData.append('file', fileOfBlob, `${pdfName}.png`);formData.append('dir', 'purchase');const response = await fetch(config.api.pictureUpload, {method: 'POST',headers: {'x-access-token': getToken(),},body: formData,});if (response.ok) {const data = await response.json();return {uid: uid,name: `${pdfName}.png`,status: 'done',url: data.data,};}return null;}//  pdf转图片const processAllPages = async (numpage: any, pdfFile: any, pdfName: any, uid: any, type: any) => {const arr: any = [];const pdfImgArr:any = []//  pdf可能不止一个页面,循环提取for (let i = 1; i < numpage; i++) {const imgData = await processPage(i, pdfFile, pdfName, uid, type);if (imgData) {arr.push(imgData);pdfImgArr.push(imgData.url)}}setUploadingImages(false);//  因为我需要跟别的接口上传的图合并 ,所以做了存储dispatch<PurchaseOrderAction>({type: 'purchaseOrder/updateState',payload: {pdfImgArr},})setSupportFileList(arr);};const uploadProps: UploadProps = {action: config.api.pictureUpload,headers: {'x-access-token': getToken()!,},data: { dir: 'purchase' },listType: 'picture-card',showUploadList: false,};//  生成图片格式function dataURLtoFile(dataURI: any, type: any) {let binary = atob(dataURI.split(',')[1]);let array = [];for (let i = 0; i < binary.length; i++) {array.push(binary.charCodeAt(i));}return new Blob([new Uint8Array(array)], { type: type });}//  上传的文件 const handleUploadSupportImages = (file: UploadChangeParam<UploadFile<any>>) => {let name = file.file.name.split('.')[0]let uid = file.file.uidlet type = 'image/png'const reader = new FileReader()reader.readAsArrayBuffer(file.file.originFileObj)reader.onload = function () {const pdfFile = reader.result;let loadingTask = pdfjsLib.getDocument(pdfFile);loadingTask.promise.then((pdf: any) => {setPageNumbers(pdf.numPages);let numpage = Number(pdf.numPages) + 1if (numpage > 9) {Toast.fail("超过数量限制!");return}processAllPages(numpage, pdf, name, uid, type);}).catch((error: any) => {console.log(error);}).finally(() => {setLoading(false);});}if (file.file.status === 'uploading') {setUploadingImages(true);return;}if (file.file.status === 'done') {const { response } = file.file;supportImages.push(response.data);setSupportImages(supportImages);if (response.success) {dispatch<PurchaseOrderAction>({type: 'deliveryDetail/updateState',payload: {},});setUploadingImages(false);} else {message.error(response.message);setUploadingImages(false);}}};//预览const handlePreview = (file: UploadFile<any>) => {setPreviewImage(file.url! || file.thumbUrl!)setPreviewVisible(true)}const uploadImagesButton = (<div>{uploadingImages ? <LoadingOutlined /> : <PlusOutlined />}<div style={{ marginTop: 8 }}>上传pdf</div></div>);const handleCancelPreview = () => {setPreviewVisible(false)}return (<><Form.Item{...formItemLayout}label="导入pdf文件"hasFeedbackstyle={{ marginTop: '15px' }}><Upload{...uploadProps}showUploadList={true}multiple={true}accept='.pdf'maxCount={1}onPreview={handlePreview}onChange={(info) => {handleUploadSupportImages(info)}}showUploadList={{showRemoveIcon:false}}fileList={supportFileList}>{uploadImagesButton}</Upload></Form.Item><Modalopen={previewVisible}title='图片预览'footer={null}onCancel={handleCancelPreview}><img alt="example" style={{ width: '100%' }} src={previewImage} /></Modal><canvas id="pdf" style={{ width: '0px' }} /></>);
};export default PdfViewer;

写的可能还有些需要优化的,但是我已经累了,暂时先这样吧

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高性能跨平台网络通信框架 HP-Socket v6.0.2

项目主页 : http://www.oschina.net/p/hp-socket开发文档 : https://www.docin.com/p-4592706661.html下载地址 : https://github.com/ldcsaa/HP-SocketQQ Group: 44636872, 663903943 v6.0.2 更新 一、主要更新 优化Linux通信组件多路复用处理架构&#xff0c;避免“惊群”问…

计算机的错误计算(六十三)

摘要 计算机的错误计算&#xff08;五十六&#xff09;探讨了大数的正切函数值的错误计算。本节讨论大数的余切函数的计算精度问题。 例1. 已知 计算 不妨用 3种方法计算。 (1) 在 Python 中利用 直接贴图&#xff1a; (2) 在 Java 中利用 若运行下列代码 import ja…

高密度互连HDI

HDI&#xff08;High Density Interconnector&#xff0c;高密度互连&#xff09;是一种先进的PCB技术&#xff0c;在有限的空间内&#xff0c;通过使用微细过孔和精细的布线来提高电路板的集成度。 特点&#xff1a; 微细过孔&#xff08;Microvias&#xff09;&#xff1a;…

城V4系列版本开源前后端uniapp代码

本文来自&#xff1a;智慧同城V4系列版本开源前后端uniapp代码 - 源码1688 应用介绍 演示地址&#xff1a;https://tongchengsaas.88881111.icu/ 账号&#xff1a;ceshi 密码&#xff1a;12345678 前端演示&#xff1a; 测试环境 php7.2mysql5.6ningx 安装拓展 ioncube&#x…

来看看设计日志组件SDK的基操

一、总览 设计一个日志组件来监控业务中的流程节点&#xff1b;我们需要分三步&#xff1b; 获取数据整理数据上传数据 二、获取数据 日常项目中使用的日志组件有&#xff1a;logback log4j: 优点&#xff1a;成熟稳定&#xff0c;灵活性高&#xff0c;性能良好&#xff0…

Windows平台RTSP|RTMP播放器如何实时调节音量

我们在做Windows平台RTSP、RTMP播放器的时候&#xff0c;有这样的技术需求&#xff0c;特别是多路监控的时候&#xff0c;并不是每一路audio都需要播放出来的&#xff0c;所以&#xff0c;这时候&#xff0c;需要有针对音量调节的设计&#xff1a; /** smart_player_sdk.cs* C…

★ C++基础篇 ★ 栈和队列

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;我将继续和大家一起学习C基础篇第八章----栈和队列 ~ 目录 一 容器适配器 二 deque的简单介绍 2.1 deque的原理介绍 2.2 deque vector list 的优缺点 2.2.1 vector 2.2.2 list 2.2.3 deque 2.3 为什么选择deq…

ECMAScript性能优化技巧与陷阱

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言 ECMAScript&#xff0c;即JavaScript&#xff0c;是一种广泛应用于Web开发中的脚本语言。随着现代Web应用的复杂度日益增加&#xff0c;如何优化JavaScript的性能变得至关重要。性能优化不仅能提高应用的响应速度&#x…

排序算法【冒泡排序】

一、原理 冒泡排序的原理比较简单&#xff0c;就是将待排序区域的数值挨个向后对比&#xff0c;直到比较到已排序的边界&#xff0c;就纳入已排序区域。 二、代码如下所示&#xff1a; #include <stdio.h> #include "test.h"/* 冒泡排序 */ void bubble_sort(…

【JavaEE】深入浅出:Spring Boot配置文件全解析

目录 SpringBoot 配置⽂件配置⽂件作⽤SpringBoot配置⽂件 配置⽂件快速⼊⼿配置⽂件的格式properties 配置⽂件说明properties 基本语法读取配置⽂件properties 缺点分析 yml 配置⽂件说明yml 基本语法yml 使⽤进阶yml 配置不同数据类型及 null配置对象配置集合配置Map yml优缺…

NVDLA专题1:NVDLA框架介绍

NVDLA概述 深度学习的计算部分主要可以分为4部分&#xff1a;卷积、激活单元&#xff08;神经元&#xff09;、池化和归一化。由于每个运算模块都有比较独特的共享特征&#xff0c;因此非常适合给每个模块设计一个对应的特殊硬件实现&#xff1a;内存访问模式容易预测并且很容…

边缘智能:让每一个温室都成为计算中心

&#xff08; 于景鑫 国家农业信息化工程技术研究中心&#xff09;当人工智能的浪潮席卷全球&#xff0c;大语言模型&#xff08;LLM&#xff09;引领智能风潮之时&#xff0c;"智慧农业"也摩拳擦掌跃跃欲试。设施农业作为现代农业的翘楚&#xff0c;正站在数智化变革…

社交媒体分析:如何利用Facebook的数据提升业务决

在数字化时代&#xff0c;社交媒体已经成为企业战略中不可或缺的一部分。Facebook&#xff0c;作为全球最大的社交平台之一&#xff0c;提供了丰富的数据资源&#xff0c;这些数据不仅能够帮助企业了解市场趋势&#xff0c;还能提升业务决策的精准度。本文将探讨如何有效利用Fa…

四路一体行车记录仪,语音提示注意行人,保障车辆行驶安全

在叉车、货车、客车等行业中&#xff0c;随着运输业务量的不断增加&#xff0c;行车安全问题已经成为了一大难题。经常会发生车祸、司乘人身安全无保障、货物损失等意外情况&#xff0c;这些事件不仅会给企业带来经济损失&#xff0c;也会影响对应行业的整体形象。 如何提高运…

深入了解指针(7)

文章目录 1.qrost的使用2.qrost函数的模拟实现 1.qrost的使用 qrost—库函数—可以实现任意数据类型的快速排序。 void qsort(void* base, //base中存放的是待排序数组的第一个元素的地址 size_t num, //num存放的是base指向的数组中的元素个数 size_t size, //size是base指向…

《学会 SpringBoot 系列 · spring.factories 详解》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

mysql 物理备份 MySQL 全量备份 增量备份 差异备份 日志备份万字长文 1.3万字

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循版权协议&#xff0c;转载请附上原文出处链接和本声明 注意&#xff0c;通常 完备增备&#xff0c;日志&#xff08;binlog)备&#xff0c;结合使用 差异则根据具体情况选用。 此备份过程 属于公司 常用的单个数据…

凹凸纹理概念

1、凹凸纹理 纹理除了可以用来进行颜色映射外&#xff0c;另外一种常见的应用就是进行凹凸映射。凹凸映射的目的是使用一张纹理来修改模型表面的法线&#xff0c;让我们不需要增加顶点&#xff0c;而让模型看起来有凹凸效果。原理&#xff1a;光照的计算都会利用法线参与计算&…

数的个位相加

给定一个非负整数 num&#xff0c;反复将各个位上的数字相加&#xff0c;直到结果为一位数。返回这个结果。 示例 1: 输入: num 38输出: 2 解释: 各位相加的过程为&#xff1a; 38 --> 3 8 --> 11 11 --> 1 1 --> 2 由于 2 是一位数&#xff0c;所以返回 2。…

搜维尔科技:驾驶模拟器背后的技术: Varjo的虚拟/混合现实 (VR/XR)提供独特的优势,最终加快汽车开发创新的步伐

专业驾驶模拟器广泛应用于车辆开发&#xff0c;帮助汽车行业在开发过程的早期做出更好的设计决策。总体目标是为测试驾驶员提供最真实的驾驶体验&#xff0c;包括动态动作和声音&#xff0c;并测试控制算法或辅助系统等功能。环境越真实&#xff0c;驾驶员的体验就越接近最终车…