解决wangEditor从word复制粘贴图片,带有页眉页脚的问题

 话不多说,直接贴代码。

rtf数据能提取到页眉页脚图片的原因:

    提取 Word 文档中包含的所有图像数据,包括页眉和页脚中的图像数据。这是因为 RTF(Rich Text Format)是一种标记语言,可以在其中嵌入文本、图像和其他媒体类型的数据。在 Word 中,页眉和页脚的内容也可以通过 RTF 格式进行描述和呈现。

//改写wangEditor的粘贴
  editorConfig.customPaste = (editor, event) => {

    // 获取粘贴的html部分(??没错粘贴word时候,一部分内容就是html),该部分包含了图片img标签
    let html = event.clipboardData.getData('text/html');

    // 获取rtf数据(从word、wps复制粘贴时有),复制粘贴过程中图片的数据就保存在rtf中
    const rtf = event.clipboardData.getData('text/rtf');

    if (html && rtf) { // 该条件分支即表示要自定义word粘贴

      // 列表缩进会超出边框,直接过滤掉
      html = html.replace(/text\-indent:\-(.*?)pt/gi, '')

      // 从html内容中查找粘贴内容中是否有图片元素,并返回img标签的属性src值的集合
      const imgSrcs = findAllImgSrcsFromHtml(html);

      // 如果有
      if (imgSrcs && Array.isArray(imgSrcs) && imgSrcs.length) {

        // 从rtf内容中查找图片数据
        const rtfImageData = extractImageDataFromRtf(rtf);
        debugger
        // 如果找到
        if (rtfImageData.length) {

          // TODO:此处可以将图片上传到自己的服务器上

          // 执行替换:将html内容中的img标签的src替换成ref中的图片数据,如果上面上传了则为图片路径
          html = replaceImagesFileSourceWithInlineRepresentation(html, imgSrcs, rtfImageData)
          editor.dangerouslyInsertHtml(html);

        }
      }

      // 阻止默认的粘贴行为
      event.preventDefault();
      return false;
    } else {
      return true;
    }
  }

  //从html中获取img的src集合
  const findAllImgSrcsFromHtml = (htmlData) => {

    let imgReg = /<img.*?(?:>|\/>)/gi; //匹配图片中的img标签
    let srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i; // 匹配图片中的src

    let arr = htmlData.match(imgReg); //筛选出所有的img
    if (!arr || (Array.isArray(arr) && !arr.length)) {
      return false;
    }

    let srcArr = [];
    for (let i = 0; i < arr.length; i++) {
      let src = arr[i].match(srcReg);
      // 获取图片地址
      srcArr.push(src[1]);
    }

    return srcArr;
  }

  //从rtf中获取所有的图片数据
  const extractImageDataFromRtf = (rtfData, ignoreHeadersFooters = true) => {
    if (!rtfData) {
      return [];
    }

    const regexPictureHeader = /{\\pict[\s\S]+?({\\\*\\blipuid\s?[\da-fA-F]+)[\s}]*/
    const regexPicture = new RegExp('(?:(' + regexPictureHeader.source + '))([\\da-fA-F\\s]+)\\}', 'g');
    const images = rtfData.match(regexPicture);
    const result = [];

    if (images) {
      for (const image of images) {
        let imageType = false;

        if (image.includes('\\pngblip')) {
          imageType = 'image/png';
        } else if (image.includes('\\jpegblip')) {
          imageType = 'image/jpeg';
        }

        if (imageType) {
          //是否跳过页眉页脚
          if (ignoreHeadersFooters) {
            const headerFooterRegex = /{\\header[\s\S]+?}\\par|{\\footer[\s\S]+?}\\par/g;
            if (headerFooterRegex.test(image)) {
              continue;
            }
          }
          result.push({
            hex: image.replace(regexPictureHeader, '').replace(/[^\da-fA-F]/g, ''),
            type: imageType
          });
        }
      }
    }

    return result;
  }

  //将html内容中img标签的属性值替换
  const replaceImagesFileSourceWithInlineRepresentation = (htmlData, imageSrcs, imagesHexSources, isBase64Data =
    true) => {
    if (imageSrcs.length === imagesHexSources.length) {
      for (let i = 0; i < imageSrcs.length; i++) {
        const newSrc = isBase64Data ?
          `data:${imagesHexSources[i].type};base64,${_convertHexToBase64(imagesHexSources[i].hex)}` :
          imagesHexSources[i];

        htmlData = htmlData.replace(imageSrcs[i], newSrc);
      }
    }

    return htmlData;
  }

  //十六进制转base64
  const _convertHexToBase64 = (hexString) => {
    return btoa(hexString.match(/\w{2}/g).map(char => {
      return String.fromCharCode(parseInt(char, 16));
    }).join(''));
  }



  // 及时销毁 editor ,重要!
  useEffect(() => {
    return () => {
      if (editor == null) return
      editor.destroy()
      setEditor(null)
    }
  }, [editor])
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值