index.js 2.93 KB
import React, { useEffect, useRef, useState } from "react";
import { Button, Modal, Image } from "antd";
import { CloseCircleOutlined } from "@ant-design/icons";

import * as commonConfig from "@/utils/config";
import jsPreviewDocx from "@js-preview/docx";
import jsPreviewExcel from "@js-preview/excel";
import jsPreviewPdf from "@js-preview/pdf";
import "@js-preview/docx/lib/index.css";
import "@js-preview/excel/lib/index.css";

import styles from "./index.less";
import { message } from "antd";

const CommonFilePreviewComponent = props => {
  const {
    url = "",
    visible,
    width = "100%",
    height = "100%",
    onCancel,
    app
  } = props;

  if (!visible) return "";

  if (!url) {
    message.warning("文件地址为空");
    onCancel && onCancel();
    return "";
  }

  const title = url
    .split("/")
    .pop()
    .split("_")
    .pop();

  const bLocalFile = url.startsWith("./");
  const fileUrl = bLocalFile
    ? `${location.origin}/${url.split("./")[1]}`
    : `${commonConfig.file_host}file/download?savePathStr=${encodeURIComponent(
        url
      )}&sModelsId=100&token=${app.token}`;

  const fileType = title
    .split(".")
    .pop()
    .toUpperCase();

  const officeRef = useRef(null);
  const [txtContent, setTxtContent] = useState("");
  useEffect(
    () => {
      if (fileType === "XLSX") {
        const myExcelPreviewer = jsPreviewExcel.init(officeRef.current);
        myExcelPreviewer.preview(fileUrl);
      } else if (fileType === "DOCX") {
        const myDocxPreviewer = jsPreviewDocx.init(officeRef.current);
        myDocxPreviewer.preview(fileUrl);
      } else if (fileType === "PDF") {
        const myDocxPreviewer = jsPreviewPdf.init(officeRef.current);
        myDocxPreviewer.preview(fileUrl);
      } else if (fileType === "TXT") {
        fetch(fileUrl)
          .then(response => response.text())
          .then(data => setTxtContent(data));
      }
    },
    [url]
  );

  return (
    <Modal
      open={visible}
      width={width}
      height={height}
      style={{
        top: 0,
        padding: 0
      }}
      getContainer={() => document.querySelector("#xlyMesContent")}
      mask={false}
      footer={null}
      onCancel={onCancel}
      closeIcon={
        <Button
          type="link"
          icon={<CloseCircleOutlined />}
          className={styles.close}
          onClick={onCancel}
        />
      }
    >
      <div className={styles.filePreview}>
        <div className={`${styles.title} ${bLocalFile ? styles.title1 : ""}`}>
          {title}
        </div>
        <div className={styles.fileContent} ref={officeRef} key={url}>
          {["PNG", "SVG", "JPG", "JPEG", "GIF", "BMP", "TIFF", "ICO"].includes(
            fileType.toUpperCase()
          ) && <Image src={fileUrl} />}
          {fileType === "TXT" && (
            <div className={styles.txtContent}>{txtContent}</div>
          )}
        </div>
      </div>
    </Modal>
  );
};

export default CommonFilePreviewComponent;