解决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])
参考文章:http://blog.ncmem.com/wordpress/2023/09/16/%e8%a7%a3%e5%86%b3wangeditor%e4%bb%8eword%e5%a4%8d%e5%88%b6%e7%b2%98%e8%b4%b4%e5%9b%be%e7%89%87%ef%bc%8c%e5%b8%a6%e6%9c%89%e9%a1%b5%e7%9c%89%e9%a1%b5%e8%84%9a%e7%9a%84%e9%97%ae%e9%a2%98/
欢迎入群一起讨论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2020-09-16 wangEditor - 支持word上传的富文本编辑器
2020-09-16 umeditor - 支持word上传的富文本编辑器
2020-09-16 百度ueditor - 支持word上传的富文本编辑器
2020-09-16 ueditor - 支持word上传的富文本编辑器
2020-09-16 在线 - 支持word上传的富文本编辑器
2020-09-16 web - 支持word上传的富文本编辑器
2020-09-16 html5 - 支持word上传的富文本编辑器