0
点赞
收藏
分享

微信扫一扫

富文本编辑器如何能实现直接粘贴把图片上传到服务器中

code_balance 2022-09-05 阅读 59

当前功能基于PHP,其它语言流程大抵相同。​

大概流程:

1. 将docx文件上传到服务器中

2. 使用PHPoffice/PHPword实现将word转换为HTML

3. 将HTML代码返回并赋值到编辑器中


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​

1​

2.2 自定义文件转换类​

实现上传文件,并将文件转换为HTML​

直接将ueditor自带的上传文件"ueditor\php\Uploader.class.php"类复制到自定义类相同目录下​

自定义WordToHtmlController.class.php文件:​


<?php​


class WordToHtmlController​

{​

public function index()​

{​

require 'vendor/autoload.php';​


$base64 = "upload";​


$config = array(​

"pathFormat" => '/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 = '<form id="edui_form_' + timestrap + '" target="edui_iframe_' + timestrap + '" method="POST" enctype="multipart/form-data" actinotallow="' + me.getOpt('serverUrl') + '" ' +​

'style="' + btnStyle + '">' +​

'<input id="edui_input_' + timestrap + '" type="file" accept="application/msword" name="' + me.options.wordFieldName + '" ' +​

'style="' + btnStyle + '">' +​

'</form>' +​

'<iframe id="edui_iframe_' + timestrap + '" name="edui_iframe_' + timestrap + '" style="display:none;width:0;height:0;border:0;margin:0;padding:0;position:absolute;"></iframe>';​


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', '<img class="loadingclass" id="' + loadingId + '" src="' + me.options.themePath + me.options.theme +'/images/spacer.gif" title="' + (me.getLang('wordupload.loading') || '') + '" >');​


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'];​


————————————————​

版权声明:本文为CSDN博主「Cold autumn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。​


至此,配置完成,结果示意图:​

富文本编辑器如何能实现直接粘贴把图片上传到服务器中_php_02


富文本编辑器如何能实现直接粘贴把图片上传到服务器中_php_03


富文本编辑器如何能实现直接粘贴把图片上传到服务器中_上传_04


更多详细资料可以参考这篇文章:

​​http://blog.ncmem.com/wordpress/2019/08/12/ueditor-word%E5%9B%BE%E7%89%87%E8%BD%AC%E5%AD%98%E4%BA%A4%E4%BA%92/​​



举报

相关推荐

0 条评论