react中封裝一個預覽.doc和.docx文件的組件

主要用到了mammoth這個插件,mammoth.js?是一個JavaScript庫,主要用于將Microsoft Word文檔(.docx格式)轉換為HTML。它可以通過Node.js環境使用,也可以直接在瀏覽器中使用。

關鍵代碼:

import mammoth from 'mammoth';
import { useEffect, useState, useRef } from 'react';
import { Slider, Spin, Space } from 'antd';
import './index.global.less';
import { type } from 'os';
import { parse } from 'path';interface Props {filePath: string;type: string;screenFlag: string;isReadingMode: boolean;
}
// react中封裝一個預覽.doc和.docx文件的組件
const DocView: (props: Props) => JSX.Element = (props: Props) => {const [docDom, setDocDom] = useState(<Space size="large" className="icon-loading"><Spin size="large" /></Space>);const [textDom, setTextDom] = useState('');const [scale, setScale] = useState(180);const [warpClassName, setWarpclassName] = useState(['view-warper']);const textInput = useRef(null);const { filePath, type, screenFlag, isReadingMode } = props;const mOptions = {includeDefaultStyleMap: true,convertImage: mammoth.images.imgElement(function (image) {return image.read('base64').then(function (imageBuffer) {if (image.contentType === 'image/x-wmf') {return {}}return {src: 'data' + image.contentType + ';base64,' + imageBuffer,}});}),};useEffect(() => {return () => {setDocDom('');<Space size="large" className="icon-loading"><Spin size="large" /></Space>}}, []);// 引入全局樣式類名(具體樣式我就不展示了)useEffect(() => {const name = ['view-warper'];if (type === 'doc' || type === 'docx') {name.push('docx-warp');} else {name.push('text-warp');}if (screenFlag) {name.push('big-screen');}else {name.push('small-screen');}if (isReadingMode) {name.push('reading-mode');}else {name.push('normal-mode');}setWarpclassName(name);if (!screenFlag) {setScale(100);}}, [screenFlag, type, isReadingMode]);useEffect(() => {if (type === 'txt' && !textDom) {return false;}if (scale / 100 < 1) {textInput.current.style.transformOrigin = 'top center';} else {textInput.current.style.transformOrigin = 'left top';}}, [scale]);const handleScale = value => {setScale(value);};useEffect(() => {setDocDom(<Space size="large" className="icon-loading"><Spin size="large" /></Space>);if (!filePath) {return}if (type === 'txt') {// 以自己項目實際接口為準api.getDocumentDetailAfter(filePath).then((res: any) => {if (res) {setTextDom(res);}else {setTextDom('該文檔沒有任何內容');}textInput.current.style.transformOrigin = 'left top';}).catch((error: any) => {throw new Error(error);})}if (type === 'doc' || type === 'docx') {const jsonFile = new XMLHttpRequest();jsonFile.open('POST', '/xxx/xxx', true);jsonFile.setRequestHeader('Content-Type', 'application/json');jsonFile.send(filePath);jsonFile.responseType = 'arraybuffer';jsonFile.onreadystatechange = () => {if (jsonFile.readyState === 4 && jsonFile.status === 200) {mammoth.convertToHtml({ arrayBuffer: jsonFile.response },mOptions).then((result: any) => {setDocDom(parse(result.value));textInput.current.style.transformOrigin = 'left top';}).catch(a => {throw new Error(a);setDocDom(<div className="res-error"><p>無法查看此文檔</p><p>請檢查重新上傳docx文件</p></div>);})} else if (jsonFile.status !== 200) {setDocDom(<div className="res-error"><p>網絡超時,請稍后再試</p></div>);}}}}, [filePath]);return (<div className={warpClassName.join(' ')}>{(type === 'doc' || type === 'docx')&& <divid="docx"style={{ transform: `scale(${scale / 100})` }}className='docx-content'ref={textInput}>{docDom}</div>}{(type === 'txt')&& (textDom ? <textareaid="txt"className="txt-content"style={{ transform: `scale(${scale / 100})` }}ref={textInput}value={textDom}></textarea> : docDom)}{(type !== 'txt' && screenFlag)&& <div className="docx-footer"><div className="slider-warp"><aclassName="slider-icon more-icon"onClick={() => setScale(setScale(~~scale + 5))}/><SliderclassName="slider"min={0}max={100}defaultValue={100}onChange={handleScale}value={scale}tooltipVisible={false}/><a className="slider-icon less-icon" onClick={() => setScale(setScale(~~scale - 5))}></a></div></div>}</div>)}

index.global.less代碼如下:

.view-warper {.icon-loading {align-items: center;justify-content: center;width: 100%;height: 100%;}.docx-warp {height: calc(100% - 40px);width: 100%;overflow: auto;}.res-error {padding: 108px 32px;height: 250px;transform: translate(0, 100%);position: relative;text-align-last: center;background: url(./error.png) top center no-repeat; // 注意項目圖片路徑p {text-indent: 0;margin-bottom: 0;}}#docx {height: 100%;padding: 10px;flex: 1;.res-error {padding: 108px 32px;height: 250px;transform: translate(0, 100%);position: relative;text-align-last: center;background: url(./error.png) top center no-repeat; // 注意項目圖片路徑p {text-indent: 0;margin-bottom: 0;}}img {max-width: 80%;display: flex;margin: 0 auto;}html {overflow-y: scroll;font-family: helvetica, arial, sans-serif;}body {margin: 0;padding: 0;}h3+p {margin-left: 40px;}h3+p+ul,h3+ol {margin-left: 40px;}h2+ul {margin-left: 60px;}h3+ol {margin-left: 60px;}.container {overflow: auto;max-width: 940px;margin: 0 auto;}.banner {overflow: auto;margin-bottom: 20px;background-color: #555;color: #fff;}.banner a {color: #fff;}.banner h1 {font-size: 20px;line-height: 2;margin: .5em 0;}.span8,.span4 {float: left;}.span8 {width: 620px;}.span4 {margin: 0 0 0 20px;}.well {background-color: #f2f2f2;border: 1px solid #ccc;padding: 1em;min-height: 200px;}.messages .warning {color: #c60;}li {list-style: decimal;margin-bottom: 10px;}p {margin-bottom: 10px;line-height: 25;text-indent: 60px;}p+ol {margin-left: 50px;}h1 {text-align: center;font-weight: bolder;font-size: 26px;margin: 20px 0;}::marker {color: blue;font-size: 1.2em;display: none;content: '';}ul {list-style: none;}strong {font-size: 24px;}h2 {padding-left: 30px;}table {border-collapse: collapse;margin: 24px auto;font-size: 0.9em;font-family: sans-serif;box-shadow: 0 0 20px rgba(0, 0, 0, .15);table-layout: fixed;width: 90%;strong {font-size: 12px;}}table td p {border-bottom: none;}table thead tr {background-color: #1ab394;color: #fff;text-align: left;}table li,table p {margin-bottom: 10px;margin-left: 0;border-bottom: 1px solid #e7e7e7;padding-bottom: 10px;padding-top: 15px;}table th,.styled-table td {padding: 12px 15px;}table tbody tr {border-bottom: 1px solid #ddd;}table tbody tr:last-of-type {border-bottom: 2px solid #1ab394;}table tbody tr.active-row {font-weight: bolder;color: #1ab394;}}.docx-footer {height: 40px;border-top: 1px solid gray;position: fixed;width: inherit;right: 424px;background: #fff;bottom: 0;.slider-warp {display: flex;align-items: center;margin-right: 25px;height: 40px;flex-direction: row-reverse;.slider {width: 80px;}.slider-icon {display: inline-block;width: 18px;height: 18px;background-position: top center;background-size: 100%;cursor: pointer;}.more-icon {background-image: url('./more.png');}.less-icon {background-image: url('./less.png');}}}.ant-slider-handle,.ant-slider-handle.ant-tooltip-open {border: 1px solid #2468f2;}.ant-slider-track {background-color: #2468f2;border-radius: 5px;z-index: 111;}.ant-slider-handle {z-index: 112;}.ant-slider-step {background-color: #91d5ff;z-index: 1;border-radius: 5px;}
}.text-warp {height: calc(100% - 60px);margin: 12px auto;text-align: center;.txt-content {padding: 10px;}textarea {width: 90%;height: 100%;border: none;resize: none;outline: none !important;overflow: auto;&:focus {border: none;outline: none !important;}}
}.docx-warp {height: calc(~'100% - 45px');background: #fff;margin: 12px auto 13px;overflow: auto;width: 93%;#docx {&>p:nth-child(2)>strong {font-size: 18px;}&>p:nth-child(3) {margin-top: 100px;text-align: center;}&>p:nth-child(4) {margin-bottom: 100px;text-align: center;}&>p:nth-child(5) {margin-bottom: 100px;text-align: center;}&>p>a {color: #333;text-align: center;}&>ul {li {margin-left: 0;}}&>h3 {margin: 20px 60px 20px;}}
}.normal-mode {width: 93%;.docx-footer {width: inherit;right: 424px;}
}.reading-mode {width: 98%;.docx-footer {left: 0;right: 0;width: 100%;}
}

基本上實現了查看word文檔內容要求的展示內容,圖片+文字說明的形式,代碼可鞥有些冗余,還有需要優化的地方.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903680.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903680.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903680.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c#WebsocketSever

這是一個winFrom的小工具&#xff0c;用于再本機創建一個c#服務的項目。 1、將本機ip地址改為左上角Ip&#xff0c;注意沒有“&#xff1a;”后的部分&#xff0c;那是端口號。 2、點擊中間按鈕&#xff0c;啟動服務器 3、如果啟動成功&#xff0c;會在下面顯示啟動成功&…

頂會招牌idea:機器學習+組合優化 優秀論文合集

2025深度學習發論文&模型漲點之——機器學習組合優化 機器學習&#xff08;ML&#xff09;與組合優化&#xff08;CO&#xff09;的交叉研究已成為運籌學與人工智能領域的前沿方向。傳統組合優化方法&#xff08;如分支定界、動態規劃&#xff09;雖在理論上有嚴格的性能保…

服務器硬件老化導致性能下降的排查與優化

隨著企業數字化轉型的深入&#xff0c;服務器作為IT基礎設施的核心載體&#xff0c;其穩定性與性能直接影響業務連續性。然而&#xff0c;硬件老化導致的性能衰減問題普遍存在且易被忽視。本報告通過系統性分析服務器硬件老化現象&#xff0c;提出多維度排查方法與優化方案&…

刪除k8s某命名空間,一直卡住了怎么辦?

以 kubectl delete ns cert-manager 命令卡住為例&#xff0c;并且命名空間一直處于 Terminating 狀態&#xff0c;說明 Kubernetes 無法完成刪除操作&#xff0c;通常是因為 Finalizers 阻塞或某些資源無法正常清理。 解決方法 1. 檢查命名空間狀態 kubectl get ns cert-man…

【分享】變聲器大師[特殊字符]喬碧蘿同款變聲[特殊字符]游戲變聲[特殊字符]

多種變聲器效果可選&#xff1a;爺爺、大叔、小孩、機器人...... 使用變聲器時只需輕輕一點&#xff0c;讓你成為潮人 【應用名稱】&#xff1a;變聲器大師 【應用版本】&#xff1a;6.1.35 【應用大小】&#xff1a;116M 【測試機型】&#xff1a;小米14 【下載鏈接】:https:…

【Part 2安卓原生360°VR播放器開發實戰】第二節|基于等距圓柱投影方式實現全景視頻渲染

《VR 360全景視頻開發》專欄 將帶你深入探索從全景視頻制作到Unity眼鏡端應用開發的全流程技術。專欄內容涵蓋安卓原生VR播放器開發、Unity VR視頻渲染與手勢交互、360全景視頻制作與優化&#xff0c;以及高分辨率視頻性能優化等實戰技巧。 &#x1f4dd; 希望通過這個專欄&am…

【JavaScript】相等運算符、條件運算符

1、相等運算符 &#xff08;1&#xff09;&#xff08;相等&#xff09; 相等運算符用來比較兩個值是否相等&#xff0c;如果相等會返回true&#xff0c;否則返回false <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"…

OceanBase數據庫-學習筆記5-用戶

用戶相關命令 命令描述CREATE USER ‘username’‘host’ IDENTIFIED BY ‘password’;創建用戶。GRANT ALL PRIVILEGES ON database_name.* TO ‘test_user’‘%’;給用戶授權所有權限。GRANT SELECT, INSERT, UPDATE ON database_name.* TO ‘test_user’‘%’;給用戶授權指…

K8S Secret 快速開始

一、什么是 Secret&#xff1f; Kubernetes&#xff08;K8s&#xff09;中的 Secret 是一種用于存儲和管理敏感信息&#xff08;如密碼、令牌、證書、API 密鑰等&#xff09;的資源對象。它避免了將敏感數據明文寫入配置文件、鏡像或代碼中&#xff0c;提供了一種更安全的方式…

【分享】音頻音樂剪輯[特殊字符]人聲分離伴奏提取[特殊字符]拼接合并

音頻音樂剪輯是一款專業的剪輯軟件。在剪輯過程中&#xff0c;它可以對音頻進行拼接合成、音樂裁剪、變調變速、格式轉換&#xff0c;同時音頻音樂剪輯還是一款支持高清錄音、音頻降噪等眾多功能于一體的音頻制作軟件。 【應用名稱】&#xff1a;音頻剪輯 【應用版本】&#xf…

力扣-數據結構-二叉樹

94. 二叉樹的中序遍歷 給定一個二叉樹的根節點 root &#xff0c;返回 它的 中序 遍歷 。 示例 1&#xff1a; 輸入&#xff1a;root [1,null,2,3] 輸出&#xff1a;[1,3,2]示例 2&#xff1a; 輸入&#xff1a;root [] 輸出&#xff1a;[]示例 3&#xff1a; 輸入&#x…

oracle怎樣通過固化較優執行計劃來優化慢sql

一 問題描述 有次生產環境cpu使用率增高&#xff0c;ADDM報告提示某條sql比較耗費cpu&#xff1a; 提示&#xff1a; 在分析期間, 此 SQL 語句至少利用了 6 個不同的執行計劃 #查看該sql都有哪些執行計劃 SELECT * FROM table(DBMS_XPLAN.DISPLAY_AWR(sqlid值)); 我手動執…

基于c#,asp.net webform, sql server數據庫,在線檔案管理系統

詳細視頻: 【基于c#,asp.net webform, sql server數據庫&#xff0c;在線檔案管理系統包部署。-嗶哩嗶哩】 https://b23.tv/c1RsdRO

WebRTC SDK是什么?

?語音環境每年都在變&#xff0c;OKCC以前代理商的客群都是簡單高效外呼為主&#xff0c;今年發現變化很大。很多代理商做的終端客戶都是給其他業務系統賦能為主了。主流的還是以API對接為主&#xff0c;但是對接中發現webrtc SDK使用頻率很高。 ? ?那么什么是WebRTC SDK…

Vue3源碼學習3-結合vitetest來實現mini-vue

文章目錄 前言? 當前已實現模塊匯總&#xff08;mini-vue&#xff09;? 每個模塊簡要源碼摘要1. reactive.ts2. effect.ts3. computed.ts4. ref.ts5. toRef.ts6. toRefs.ts ? 下一階段推薦目標所有核心模塊對應的 __tests__ 測試文件&#xff0c;**帶完整注釋**? reactive.…

PH熱榜 | 2025-04-30

1. Daytona 標語&#xff1a;安全且靈活的基礎設施&#xff0c;用于運行你的人工智能生成的代碼。 介紹&#xff1a;Daytona Cloud 為 AI 智能體重塑了基礎設施&#xff0c;具備不到 90 毫秒的啟動時間、原生性能以及有狀態執行的能力&#xff0c;這些是傳統云計算所無法實現…

Android compileSdkVersion、minSdkVersion、targetSdkVersion的關系以及和Unity的關系

compileSdkVersion、minSdkVersion、targetSdkVersion的關系 參考&#xff1a;https://mp.weixin.qq.com/s?__bizMzg5MzYxNTI5Mg&mid2247494238&idx1&sn06285667d3ac1339f6d2daae840cedc8&chksmc125565280f1ad3aa127774c2d1e59eb2818f89f0cb3ed4d72145faf619…

數據庫的死鎖相關(一)

目錄 前言 一、什么死鎖 二、產生死鎖的必要條件 三、死鎖發生的具體位置和場景 1. 數據行級別死鎖&#xff08;最常見&#xff09; 2. 表級別死鎖 3. 索引間隙鎖死鎖&#xff08;InnoDB特有&#xff09; 4. 外鍵約束死鎖 5. 元數據鎖死鎖 6. 內存中的鎖結構死鎖 7.…

Three.js + React 實戰系列-3D 個人主頁:構建 Hero 場景組件(項目核心)?

在本節中&#xff0c;我們將完成整個 3D 主業項目中最核心的組件 —— Hero.jsx。 這個組件作為首頁的主視覺部分&#xff0c;整合了 3D 模型、動畫相機、交互按鈕與自適應布局&#xff0c;構建出一個立體、酷炫、可交互的主場景。 前置準備&#xff1a; ?安裝依賴&#xff…

Electron Forge【實戰】桌面應用 —— 將項目配置保存到本地

最終效果 定義默認配置 src/initData.ts export const DEFAULT_CONFIG: AppConfig {language: "zh",fontSize: 14,providerConfigs: {}, };src/types.ts export interface AppConfig {language: zh | enfontSize: numberproviderConfigs: Record<string, Recor…