You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React 18本地项目目录文件预览方案及适配库推荐

React 18 本地文件预览方案推荐

针对你需要在React 18项目中预览本地存储的多种格式文件(jpg/png/pdf/doc/docx/xls/xlsx)的需求,以下是经过验证的可行方案和适配库:

一、分格式适配的React 18兼容库

1. 图片(jpg/png):react-image

轻量且功能完善的图片组件,支持懒加载、错误占位,原生适配React 18。直接传入本地文件路径即可渲染,无需额外配置。

2. PDF:@react-pdf/renderer

目前最稳定的React PDF渲染库,完全兼容React 18。支持从本地路径、ArrayBuffer或Blob加载文件,还能自定义页码、缩放等功能。

3. Word文档(doc/docx):docx-preview

专门针对Word文档的轻量渲染库,无大型依赖,适配React 18。通过读取文件的ArrayBuffer,直接将文档内容渲染为HTML结构,保留原格式。

4. Excel表格(xls/xlsx):sheetjs/xlsx

生态成熟的表格处理库,兼容React 18。可将Excel文件解析为JSON、HTML或数组,方便结合React组件自定义渲染表格样式。

二、混合实现方案(多格式统一预览)

将上述库结合,根据文件后缀判断渲染逻辑,实现一站式预览:

核心逻辑示例

import React from 'react';
import ImagePreview from './ImagePreview';
import PdfPreview from './PdfPreview';
import DocPreview from './DocPreview';
import ExcelPreview from './ExcelPreview';

const FilePreview = ({ filePath }) => {
  const getFileExtension = () => {
    return filePath.split('.').pop().toLowerCase();
  };

  const renderPreview = () => {
    const ext = getFileExtension();
    switch (ext) {
      case 'jpg':
      case 'png':
        return <ImagePreview filePath={filePath} />;
      case 'pdf':
        return <PdfPreview filePath={filePath} />;
      case 'doc':
      case 'docx':
        return <DocPreview filePath={filePath} />;
      case 'xls':
      case 'xlsx':
        return <ExcelPreview filePath={filePath} />;
      default:
        return <div>不支持的文件格式</div>;
    }
  };

  return <div className="file-preview-container">{renderPreview()}</div>;
};

export default FilePreview;

各格式组件实现参考

图片预览组件

import React from 'react';
import Image from 'react-image';

const ImagePreview = ({ filePath }) => {
  return (
    <Image
      src={filePath}
      alt="图片预览"
      loader={<div>加载中...</div>}
      unloader={<div>图片加载失败</div>}
      style={{ maxWidth: '100%', height: 'auto' }}
    />
  );
};

export default ImagePreview;

PDF预览组件

import React, { useState } from 'react';
import { Document, Page, pdfjs } from '@react-pdf/renderer';

// 配置PDF worker
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.js`;

const PdfPreview = ({ filePath }) => {
  const [numPages, setNumPages] = useState(null);
  const [currentPage, setCurrentPage] = useState(1);

  const handleDocumentLoad = ({ numPages }) => {
    setNumPages(numPages);
  };

  return (
    <div>
      <Document file={filePath} onLoadSuccess={handleDocumentLoad}>
        <Page pageNumber={currentPage} />
      </Document>
      {numPages && (
        <div className="pdf-pagination">
          <button onClick={() => setCurrentPage(prev => Math.max(prev - 1, 1))} disabled={currentPage === 1}>
            上一页
          </button>
          <span>第 {currentPage} 页 / 共 {numPages} 页</span>
          <button onClick={() => setCurrentPage(prev => Math.min(prev + 1, numPages))} disabled={currentPage === numPages}>
            下一页
          </button>
        </div>
      )}
    </div>
  );
};

export default PdfPreview;

Word文档预览组件

import React, { useEffect, useRef } from 'react';
import { renderAsync } from 'docx-preview';

const DocPreview = ({ filePath }) => {
  const previewRef = useRef(null);

  useEffect(() => {
    const loadAndRenderDoc = async () => {
      if (!previewRef.current) return;
      const response = await fetch(filePath);
      const arrayBuffer = await response.arrayBuffer();
      await renderAsync(arrayBuffer, previewRef.current, {
        className: 'doc-preview-content',
      });
    };

    loadAndRenderDoc();
  }, [filePath]);

  return <div ref={previewRef} className="doc-preview-container" />;
};

export default DocPreview;

Excel表格预览组件

import React, { useEffect, useState } from 'react';
import * as XLSX from 'xlsx';

const ExcelPreview = ({ filePath }) => {
  const [tableContent, setTableContent] = useState('');

  useEffect(() => {
    const loadAndRenderExcel = async () => {
      const response = await fetch(filePath);
      const arrayBuffer = await response.arrayBuffer();
      const workbook = XLSX.read(arrayBuffer, { type: 'array' });
      const firstSheet = workbook.SheetNames[0];
      const worksheet = workbook.Sheets[firstSheet];
      const html = XLSX.utils.sheet_to_html(worksheet, { id: 'excel-preview-table' });
      setTableContent(html);
    };

    loadAndRenderExcel();
  }, [filePath]);

  return (
    <div className="excel-preview-container">
      <div dangerouslySetInnerHTML={{ __html: tableContent }} />
    </div>
  );
};

export default ExcelPreview;

三、注意事项

  1. 本地文件路径处理:若文件存放在项目public目录下,直接使用相对路径(如/uploads/test.pdf);若在src目录下,需通过import或require导入,确保Webpack能正确打包资源。
  2. 大文件优化:对于大体积的PDF、Word或Excel文件,建议添加加载状态提示,必要时实现分片加载或懒加载,避免阻塞页面渲染。
  3. 样式自定义:各库渲染的内容可通过自定义CSS类调整样式,匹配项目整体风格。

内容的提问来源于stack exchange,提问作者Jepthe Tan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:25:13