勤奋鸟旗下 软件定制开发 安全交付平台!一次合作,终身售后!全程项目经理一对一跟进测试!公司以自研团队结合搭档圈,为用户提供安全快速稳定的软件源码开发服务!

百度富文本ueditor实现导入word并将内容显示到编辑器中

2024-09-04 17:20:52
复制链接

4623

tp5 html ueditor实现导入word
1 编辑器配置修改
1.1 新增上传word json配置
在ueditor\php\config.json中新增如下配置:
 /* 上传word配置 */
    "wordActionName": "wordupload", /* 执行上传视频的action名称 */
    "wordFieldName": "upfile", /* 提交的视频表单名称 */
    "wordPathFormat": "/public/uploads/word/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
    "wordMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
    "wordAllowFiles": [".docx"] /* 仅支持docx格式的word */
1.2 修改编辑器配置文件
1.2.1 在工具栏上新增按钮
在ueditor\ueditor.config.js文件中,新增按钮名称"wordupload",并添加鼠标悬浮提示,如下所示:
 //工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义
        , toolbars: [[
            'fullscreen', 'source', '|', 'undo', 'redo', '|',
            'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
            'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
            'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
            'directionalityltr', 'directionalityrtl', 'indent', '|',
            'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',
            'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
            'simpleupload', 'insertimage', 'emotion', 'scrawl', 'insertvideo', 'music', 'attachment', 'map', 'gmap', 'insertframe', 'insertcode', 'webapp', 'pagebreak', 'template', 'background', '|',
            'horizontal', 'date', 'time', 'spechars', 'snapscreen', 'wordimage', '|',
            'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|',
            'print', 'preview', 'searchreplace', 'drafts', 'help', 'wordupload'
        ]]
        //当鼠标放在工具栏上时显示的tooltip提示,留空支持自动多语言配置,否则以配置值为准
        ,labelMap:{
           'wordupload': '上传word文件',
        }
在ueditor\themes\default\images\目录下新增按钮图标"word_upload.png":
导入图标
在ueditor\themes\default\css\ueditor.css文件中新增按钮样式:
.edui-for-wordupload .edui-icon {
    width: 16px;
    height: 16px;
    background: url(../images/word_upload.png) no-repeat 2px 2px !important;
}
最后在ueditor\ueditor.all.js文件中editorui["simpleupload"] = function (editor){}后面添加如下代码:
/* word上传 */
    editorui["wordupload"] = function (editor) {
        var name = 'wordupload',
            ui = new editorui.Button({
                className:'edui-for-' + name,
                title:editor.options.labelMap[name] || editor.getLang("labelMap." + name) || '',
                onclick:function () {},
                theme:editor.options.theme,
                showText:false
            });
        editorui.buttons[name] = ui;
        editor.addListener('ready', function() {
            var b = ui.getDom('body'),
                iconSpan = b.children[0];
            editor.fireEvent('worduploadbtnready', iconSpan);
        });
        editor.addListener('selectionchange', function (type, causeByUi, uiReady) {
            var state = editor.queryCommandState(name);
            if (state == -1) {
                ui.setDisabled(true);
                ui.setChecked(false);
            } else {
                if (!uiReady) {
                    ui.setDisabled(false);
                    ui.setChecked(state);
                }
            }
        });
        return ui;
    };最终图片如下1.2.2 新增语言配置
在ueditor\lang\zh-cn\zh-cn.js文件中在"simpleupload"配置下方新增以下配置:
'simpleupload':{ 'exceedSizeError': '文件大小超出限制', 'exceedTypeError': '文件格式不允许', 'jsonEncodeError': '服务器返回格式错误', 'loading':"正在上传...", 'loadError':"上传错误", 'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!' }, 'wordupload':{ 'exceedSizeError': '文件大小超出限制', 'exceedTypeError': '文件格式不允许', 'jsonEncodeError': '服务器返回格式错误', 'loading':"正在上传...", 'loadError':"上传错误", 'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!' },
在ueditor\lang\zh-cn\en.js文件中在"simpleupload"配置下方新增以下配置
'simpleupload':{ 'exceedSizeError': 'File Size Exceed', 'exceedTypeError': 'File Type Not Allow', 'jsonEncodeError': 'Server Return Format Error', 'loading':"loading...", 'loadError':"load error", 'errorLoadConfig': 'Server config not loaded, upload can not work.', }, 'wordupload':{ 'exceedSizeError': 'File Size Exceed', 'exceedTypeError': 'File Type Not Allow', 'jsonEncodeError': 'Server Return Format Error', 'loading':"loading...", 'loadError':"load error", 'errorLoadConfig': 'Server config not loaded, upload can not work.', }, 1.2.3 修改过滤配置 由于导入word时,编辑器会自动过滤掉图片等样式,所以需取消过滤 在ueditor\ueditor.config.js文件中修改如下配置:
        // xss 过滤是否开启,inserthtml等操作 ,xssFilterRules: false //input xss过滤 ,inputXssFilter: false //output xss过滤 ,outputXssFilter: false
在ueditor\ueditor.all.js文件中,修改UE.plugins[‘defaultfilter’],新增return ;如下所示:
// plugins/defaultfilter.js ///import core ///plugin 编辑器默认的过滤转换机制 UE.plugins['defaultfilter'] = function () { return; var me = this; me.setOpt({ 'allowDivTransToP':true, 'disabledTableInTable':true });
2 添加相关功能 2.1 安装PHPword
composer require phpoffice/phpword
2.2 自定义文件转换类 实现上传文件,并将文件转换为HTML 直接将ueditor自带的上传文件"ueditor\php\Uploader.class.php"类复制到自定义类相同目录下 自定义wordToHtml.class.php文件:
'/public/uploads/word/{yyyy}{mm}{dd}/{time}{rand:6}', "maxSize" => 102400000, "allowFiles" => [".docx"] ); $fieldName = 'upfile'; include 'Uploader.class.php'; $up = new Uploader($fieldName, $config, $base64); $path = ltrim($up->getFileInfo()['url'], '/'); // $phpWord = \PhpOffice\PhpWord\IOFactory::load('public/uploads/word/20211029/test.docx'); $phpWord = \PhpOffice\PhpWord\IOFactory::load($path); // 直接输出到页面显示 // $phpWord->save('php://output', 'HTML'); $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'HTML'); header("Content-Type:text/html; charset=utf-8"); exit($this->replaceImageSrc($xmlWriter->getContent())); // exit($xmlWriter->getContent()); } /** * 将HTML代码中的所有图片地址替换 * @param $content string 要查找的内容 * @return string */ private function replaceImageSrc($content) { $preg = '/(\s+src\s?\=)\s?[\'|"]([^\'|"]*)/is'; // 匹配img标签的正则表达式 preg_match_all($preg, $content, $allImg); // 匹配所有的img if (!$allImg) return $content; foreach ($allImg[0] as $k => $v) { $old = ltrim($v, '" src='); preg_match('/^(data:\s*image\/(\w+);base64,)/', $old, $temp); $tempType = $temp[2]; // 获取类型 // 判断目录是否存在,不存在时创建 $tempFilePath = 'public/uploads/word_images/' . date('Y-m-d', time()); if (!file_exists($tempFilePath)) mkdir($tempFilePath); // 拼接完整路径 $tempFileName = $tempFilePath . '/word_image_' . time() . $k . '.' . $tempType; $base64 = str_replace($temp[1], '', $old); file_put_contents($tempFileName, base64_decode($base64)); // 替换路径字符串 $content = str_replace($old, $tempFileName, $content); } return $content; } } 2.3 编辑器实现导入操作 在ueditor\ueditor.all.js文件中UE.plugin.register('simpleupload', function (){})下方新增如下方法:
/** * @description * word上传:点击按钮,直接选择文件上传 */ UE.plugin.register('wordupload', function (){ var me = this, isLoaded = false, containerBtn; function initUploadBtn(){ var w = containerBtn.offsetWidth || 20, h = containerBtn.offsetHeight || 20, btnIframe = document.createElement('iframe'), btnStyle = 'display:block;width:' + w + 'px;height:' + h + 'px;overflow:hidden;border:0;margin:0;padding:0;position:absolute;top:0;left:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity: 0;opacity: 0;cursor:pointer;'; domUtils.on(btnIframe, 'load', function(){ var timestrap = (+new Date()).toString(36), wrapper, btnIframeDoc, btnIframeBody; btnIframeDoc = (btnIframe.contentDocument || btnIframe.contentWindow.document); btnIframeBody = btnIframeDoc.body; wrapper = btnIframeDoc.createElement('div'); wrapper.innerHTML = '
' + '' + '
' + ''; wrapper.className = 'edui-' + me.options.theme; wrapper.id = me.ui.id + '_iframeupload'; btnIframeBody.style.cssText = btnStyle; btnIframeBody.style.width = w + 'px'; btnIframeBody.style.height = h + 'px'; btnIframeBody.appendChild(wrapper); if (btnIframeBody.parentNode) { btnIframeBody.parentNode.style.width = w + 'px'; btnIframeBody.parentNode.style.height = w + 'px'; } var form = btnIframeDoc.getElementById('edui_form_' + timestrap); var input = btnIframeDoc.getElementById('edui_input_' + timestrap); var iframe = btnIframeDoc.getElementById('edui_iframe_' + timestrap); domUtils.on(input, 'change', function(){ if(!input.value) return; var loadingId = 'loading_' + (+new Date()).toString(36); var allowFiles = me.getOpt('wordAllowFiles'); me.focus(); me.execCommand('inserthtml', ''); function callback(){ try{ // 获取到内容 var body = (iframe.contentDocument || iframe.contentWindow.document).body; // 获取加载中图片并关闭 var loader = me.document.getElementById(loadingId); loader.removeAttribute('id'); domUtils.removeClasses(loader, 'loadingclass'); // 向编辑器赋值 me.setContent(body.innerHTML, false); // me.execCommand('insertHtml', body.innerHTML); }catch(er){ showErrorLoader && showErrorLoader(me.getLang('wordupload.loadError')); } form.reset(); domUtils.un(iframe, 'load', callback); } function showErrorLoader(title){ if(loadingId) { var loader = me.document.getElementById(loadingId); loader && domUtils.remove(loader); me.fireEvent('showmessage', { 'id': loadingId, 'content': title, 'type': 'error', 'timeout': 4000 }); } } /* 判断后端配置是否没有加载成功 */ if (!me.getOpt('wordActionName')) { errorHandler(me.getLang('autoupload.errorLoadConfig')); return; } // 判断文件格式是否错误 var filename = input.value, fileext = filename ? filename.substr(filename.lastIndexOf('.')):''; if (!fileext || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) { showErrorLoader(me.getLang('wordupload.exceedTypeError')); return; } domUtils.on(iframe, 'load', callback); // 上传操作 // form.action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?':'&') + params); // 替换请求地址为框架后台地址 form.action = "/admin.php?m=fwordToHtml&a=index" form.method = "post" form.submit(); }); var stateTimer; me.addListener('selectionchange', function () { clearTimeout(stateTimer); stateTimer = setTimeout(function() { var state = me.queryCommandState('wordupload'); if (state == -1) { input.disabled = 'disabled'; } else { input.disabled = false; } }, 400); }); isLoaded = true; }); btnIframe.style.cssText = btnStyle; containerBtn.appendChild(btnIframe); } return { bindEvents:{ 'ready': function() { //设置loading的样式 utils.cssRule('loading', '.loadingclass{display:inline-block;cursor:default;background: url(\'' + this.options.themePath + this.options.theme +'/images/loading.gif\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}\n' + '.loaderrorclass{display:inline-block;cursor:default;background: url(\'' + this.options.themePath + this.options.theme +'/images/loaderror.png\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' + '}', this.document); }, /* 初始化word上传按钮 */ 'worduploadbtnready': function(type, container) { containerBtn = container; me.afterConfigReady(initUploadBtn); } }, outputRule: function(root){ utils.each(root.getNodesByTagName('img'),function(n){ if (/\b(loaderrorclass)|(bloaderrorclass)\b/.test(n.getAttr('class'))) { n.parentNode.removeChild(n); } }); }, commands: { 'wordupload': { queryCommandState: function () { return isLoaded ? 0:-1; } } } } }); 然后在同文件下的btnCmds变量中添加上自定义的按钮:
//为工具栏添加按钮,以下都是统一的按钮触发命令,所以写在一起 var btnCmds = ['undo', 'redo', 'formatmatch', 'bold', 'italic', 'underline', 'fontborder', 'touppercase', 'tolowercase', 'strikethrough', 'subscript', 'superscript', 'source', 'indent', 'outdent', 'blockquote', 'pasteplain', 'pagebreak', 'selectall', 'print','horizontal', 'removeformat', 'time', 'date', 'unlink', 'insertparagraphbeforetable', 'insertrow', 'insertcol', 'mergeright', 'mergedown', 'deleterow', 'deletecol', 'splittorows', 'splittocols', 'splittocells', 'mergecells', 'deletetable', 'drafts', 'wordupload'];
至此,配置完成,结果示意图:
17330196230 13230981129

多线程同步开发
项目经理1v1跟进
源码定制交付
一次合作/终身售后

微信扫码登录/注册

提示

您的诉求已经提交请等待工作人员联系,快速通过请联系管理员!

微信扫一扫快速联系

用户协议

欢迎访问我们的网站!我们非常重视用户的隐私权和信息安全,因此制定了以下用户协议,以明确我们与您之间的关系以及您在使用本网站时应遵守的条款。请您仔细阅读并同意本协议的所有条款,以便您能够合法、安全地使用本网站。如果您不同意本协议的任何内容,请立即停止使用本网站。

  1. 服务说明:本网站是一个提供定制软件开发服务和在线找技术搭档的互联网平台。我们保留随时更改、更新或暂停本网站的权利。我们会尽力确保网站的正常运行,但对于因技术问题、系统维护或其他原因导致的网站暂时不可用,我们不承担任何责任。

  2. 用户注册:用户需要通过提供手机号、微信扫码和其他必要信息来注册一个账户。您有责任保护您的用户名和密码,不得将其透露给任何第三方。对于因您的用户名和密码被泄露而导致的任何损失或损害,我们将不承担责任。

  3. 用户行为规范:用户应遵守中华人民共和国相关法律法规,不得发布或传播违法信息、侵犯他人权益的内容。用户应对其发布的内容负责,并承担因发布不当内容而引起的任何法律责任。

  4. 版权声明:本网站所包含的所有文字、图片、音频、视频等素材的著作权均归本网站所有(会员用户上传的默认承诺为不侵权的合法自有技术成果,本网站审核信息后可展示,所有权不归本网站)。未经本网站书面许可,任何单位或个人不得以任何形式复制、转载、修改或传播本网站的任何内容。对于侵犯本网站知识产权的行为,将依法追究其法律责任。

  5. 免责声明:本网站不对因使用本网站而引起的任何直接、间接、偶然、特殊或后果性的损害承担责任。包括但不限于利润损失、数据丢失、业务中断等。

  6. 适用法律和争议解决:本协议的签订、履行、解释及争议解决均适用中华人民共和国法律。如发生争议,双方应首先协商解决;协商不成的,任何一方均有权向有管辖权的人民法院提起诉讼。

  7. 本协议的解释权归本网站所有。如有未尽事宜,本网站保留最终解释权。

  8. 本协议自用户点击“同意”或“接受”按钮时生效。

同意

隐私政策

欢迎访问我们的网站!我们致力于为您提供一个安全、可靠的在线环境。本隐私政策旨在说明我们在您使用我们的网站时如何收集、使用和保护您的个人信息。请仔细阅读以下内容,以了解我们的隐私政策。

  1. 信息收集

在使用我们的网站时,我们可能会收集以下类型的信息:

a) 个人识别信息:如姓名、电子邮件地址、电话号码等。 b) 非个人识别信息:如浏览器类型、操作系统、设备类型、IP地址等。 c) 用户行为信息:如访问页面、点击链接、搜索查询等。

  1. 信息使用

我们收集的信息将用于以下目的:

a) 提供、改进和个性化我们的服务。 b) 与您联系,回应您的询问和请求。 c) 发送您请求的或我们认为对您有帮助的信息。 d) 进行市场调研和分析,以改进我们的产品和服务。 e) 防止欺诈和其他非法活动。

  1. 信息共享

我们不会出售、出租或以其他方式与第三方共享您的个人信息,除非:

a) 获得您的明确同意。 b) 与可信赖的合作伙伴共享,以提供您请求的服务。 c) 根据法律要求或政府机关的要求。 d) 为保护我们的权利、财产或安全。

  1. 信息安全

我们采取合理的安全措施,以保护您的个人信息不受未经授权的访问、披露、更改或破坏。然而,请注意,没有任何一种电子存储方法是100%安全的。

  1. Cookie和跟踪技术

我们的网站使用Cookie和类似的跟踪技术来收集有关您使用我们网站的信息。这些信息有助于我们分析和改进我们的网站,以及提供个性化的内容和广告。您可以通过浏览器设置拒绝接受Cookie,但这可能会影响您使用我们网站的能力。

  1. 第三方链接

我们的网站可能包含指向其他网站的链接。请注意,我们对其他网站的隐私政策和实践不承担任何责任。我们建议您在访问这些网站时查看其隐私政策。

  1. 隐私政策的变更

我们可能会不时更新本隐私政策。请定期查看此页面,以确保您了解我们对个人信息的最新政策。

  1. 联系我们

如果您对我们的隐私政策有任何疑问或建议,请通过以下联系方式与我们联系:

电子邮件:[wangye-101@163.com]

电话:+86-173-3019-6230

地址:中国石家庄市长安区吾悦广场2010室

感谢您的信任和支持!我们将竭诚为您提供更优质的服务。

同意