从第三方(秀米编辑器)复制粘贴图文,图片上传至本地文件夹,并在小程序端显示

        接到这个需求的时候有点诧异和迷茫,后面经过自己的一步一步摸索终于实现了这个让人头疼的需求。客户需求:从第三方(秀米编辑器)复制粘贴图文保留图文样式,并且图片批量上传至本地文件夹,并在小程序端显示。前端是vue,后端是java语言。

        这个功能是实现我试了3个富文本,分别是quillEditor,tinymce,vue-html5-editor。

        最后用vue-html5-editor这个富文本实现了,vue-html5-editor富文本从第三方复制过来时可以保留第三方的所有样式,包括文字样式,图片样式。思路:复制过来图片批量上传是在后台(JAVA)进行处理的,后台可以直接用正则表达式截取网络图片或者Base64图片上传至本地文件夹然后显示在小程序端。

        先介绍一下quillEditor这个富文本,quillEditor该富文本只能实现单个图片上传,从第三方复制黏贴过来上传无效,亲测。

        tinymce可以使用powerpaste(收费)插件进行图片批量上传,但是我公司做的是一个小项目,老板也拒绝付费去购买该插件。网上其实也可以找到powerpaste插件,可以去网盘直接下载,但是又遇到问题从网盘下载的powerpaste(不收费插件)配Tinymce4.x就会很多地方不适应的地方,该版本的兼容性肯定不行,会导致图片复制过来是空白的问题,然后又放弃了这个富文本。

        vue-html5-editor富文本虽然是个html5的富文本,但是从第三方复制过来的图文是可以保留样式的,然后百度搜索该富文本是否有批量上传图片的属性,根本没有找到,然后自己转换了想法,决定在前端点保存时把图片全部都都转成base64格式,转完之后存进数据库里发现数据量太大(5M,10M),在小程序端渲染速率太慢了。这个想法也放弃了。

        最后灵机一动发现可以把网络图片或者bsae64的图片直接在后台进行上传。不多说了,上代码。

 步骤一: 前端(vue)

在页面引入

步骤二:在main.js引入

let opt = {

// 全局组件名称,使用new VueHtml5Editor(options)时该选项无效

  name:"vue-html5-editor",

// 是否显示模块名称,开启的话会在工具栏的图标后台直接显示名称

  showModuleName:true,

// 自定义各个图标的class,默认使用的是font-awesome提供的图标

  icons: {

text:"fa fa-pencil",

color:"fa fa-paint-brush",

font:"fa fa-font",

align:"fa fa-align-justify",

list:"fa fa-list",

link:"fa fa-chain",

unlink:"fa fa-chain-broken",

tabulation:"fa fa-table",

image:"fa fa-file-image-o",

hr:"fa fa-minus",

eraser:"fa fa-eraser",

undo:"fa-undo fa",

"full-screen":"fa fa-arrows-alt",

info:"fa fa-info",

},

// 配置图片模块

  image: {

// 文件最大体积,单位字节

    sizeLimit:512 *1024 *10,

// 上传参数,默认把图片转为base64而不上传

// upload config,default null and convert image to base64

    upload: {

// url: 'https://test.xiujianshen.com/media/upload',

      url:null,

headers: {

},

params: {

},

fieldName:'file'

    },

// 压缩参数,默认使用localResizeIMG进行压缩,设置为null禁止压缩

// width和height是文件的最大宽高

    compress: {

width:300,

height:null,

quality:80

    },

// 响应数据处理,最终返回图片链接

    uploadHandler(responseText){

console.log(JSON.parse(responseText));

//      default accept json data like  {ok:false,msg:"unexpected"} or {ok:true,data:"image url"}

      var json =JSON.parse(responseText);

if(json.code ==0){

return json.data;

}else{

alert(json.message)

}

}

},

// 语言,内建的有英文(en-us)和中文(zh-cn)

  language:"zh-cn",

// 自定义语言

  i18n: {

"zh-cn": {

"align":"对齐方式",

"image":"图片",

"list":"列表",

"link":"链接",

"unlink":"去除链接",

"table":"表格",

"font":"文字",

"full screen":"全屏",

"text":"排版",

"eraser":"格式清除",

"info":"关于",

"color":"颜色",

"please enter a url":"请输入地址",

"create link":"创建链接",

"bold":"加粗",

"italic":"倾斜",

"underline":"下划线",

"strike through":"删除线",

"subscript":"上标",

"superscript":"下标",

"heading":"标题",

"font name":"字体",

"font size":"文字大小",

"left justify":"左对齐",

"center justify":"居中",

"right justify":"右对齐",

"ordered list":"有序列表",

"unordered list":"无序列表",

"fore color":"前景色",

"background color":"背景色",

"row count":"行数",

"column count":"列数",

"save":"确定",

"upload":"上传",

"progress":"进度",

"unknown":"未知",

"please wait":"请稍等",

"error":"错误",

"abort":"中断",

"reset":"重置"

    }

},

// 隐藏不想要显示出来的模块

  hiddenModules: [],

// 自定义要显示的模块,并控制顺序

  visibleModules: [

"text",

"color",

"font",

"align",

"list",

"link",

"unlink",

"tabulation",

"image",

"hr",

"eraser",

"undo",

"full-screen",

"info",

],

// 扩展模块,具体可以参考examples或查看源码

// extended modules

  modules: {

//omit,reference to source code of build-in modules

  }

};

Vue.use(VueHtml5Editor,opt);

步骤三:前台页面点提交后把富文本的全部数据都传到后台,后台代码如下

String regex ="src=['\"](.*?)['\"]";//正则表达式来匹配src属性

Pattern pattern = Pattern.compile(regex);//使用正则获取富文本里的所有图片

Matcher m = pattern.matcher(activity.getActivityContent());//传入富文本内容进行格式化

StringBuffer sb =new StringBuffer();//new一个StringBuffer

while( m.find())

{

String newUrl="";

String url = m.group(1);// 外链URL

//单个图片上传时是base64

    if(url.indexOf("data") != -1){

//去掉base64字符串的开头部分

        String base64Url = url.substring(url.indexOf(",")+1);

newUrl=GenerateImage(base64Url);

}

//复制上传是网络图片

    else {

newUrl = richImage(url);// 本地化

    }

String newSrc = String.format(" src='%s' ", newUrl);// 新的src属性

    m.appendReplacement(sb, newSrc);// 替换回去

}

m.appendTail(sb);

String ActivityContent = sb.toString();//获取替换后的富文本


上面分别把base64的图片和网络图片上传到了本地,

base64上传代码如下

/**

* base64转图片上传至本地文件夹

* @param base64str base64码

* @return

*/

public String GenerateImage(String base64str)throws Exception{

BASE64Decoder decoder =new BASE64Decoder();

//Base64解码

    byte[] b = decoder.decodeBuffer(base64str);

for (int i =0; i < b.length; ++i) {

//调整异常数据

        if (b[i] <0) {

b[i] +=256;

}

}

int x = (int) (Math.random() *1000);

String filedata = dates();

SimpleDateFormat df =new SimpleDateFormat("yyyy-MM-dd");//设置日期格式

    String date=df.format(new Date());

//new一个文件对象用来保存图片,默认保存当前工程根目录

    String realPath = SpringConfig.fileRootPath + SpringConfig.activityEditorImage+date;

File imageFile =new File(realPath);

if (imageFile.exists()) {

}else {

imageFile.mkdir();

}

String realPath1 = SpringConfig.fileRootPath + SpringConfig.activityEditorImage + date+"/" + x + filedata +".jpeg";

//生成jpeg图片

    OutputStream out =new FileOutputStream(realPath1);

out.write(b);

out.flush();

out.close();

//返回本地化后的图片路径 SpringConfig.fileRootWeb+

    String outFielPath ="/static"+SpringConfig.activityEditorImage +"/"+ date+"/"  + x + filedata +".jpeg";

return outFielPath;

}


网络图片上传代码如下:

/**

* 秀米图片转图片上传至本地文件夹

* @param imgOldUrl

* @return

*/

public String richImage(String imgOldUrl)throws Exception{

//new一个URL对象

    URL url =new URL(imgOldUrl);

//打开链接

    HttpURLConnection conn = (HttpURLConnection)url.openConnection();

//设置请求方式为"GET"

    conn.setRequestMethod("GET");

//超时响应时间为5秒

    conn.setConnectTimeout(5 *1000);

//通过输入流获取图片数据

    InputStream inStream = conn.getInputStream();

//得到图片的二进制数据,以二进制封装得到数据,具有通用性

    byte[] data =this.readInputStream(inStream);

int x = (int) (Math.random() *1000);

String filedata = dates();

SimpleDateFormat df =new SimpleDateFormat("yyyy-MM-dd");//设置日期格式

    String date=df.format(new Date());

//new一个文件对象用来保存图片,默认保存当前工程根目录

    String realPath = SpringConfig.fileRootPath + SpringConfig.activityEditorImage+date;

File imageFile =new File(realPath);

if (imageFile.exists()) {

}else {

imageFile.mkdir();

}

String realPath1 = SpringConfig.fileRootPath + SpringConfig.activityEditorImage + date+"/" + x + filedata +".jpeg";

File imageFile1 =new File(realPath1);

//创建输出流

    FileOutputStream outStream =new FileOutputStream(imageFile1);

//写入数据

    outStream.write(data);

//关闭输出流

    outStream.close();

//返回本地化后的图片路径 SpringConfig.fileRootWeb+

    String outFielPath ="/static"+SpringConfig.activityEditorImage +"/"+ date+"/"  + x + filedata +".jpeg";

return outFielPath;

}

public byte[] readInputStream(InputStream inStream)throws Exception{

ByteArrayOutputStream outStream =new ByteArrayOutputStream();

//创建一个Buffer字符串

    byte[] buffer =new byte[1024];

//每次读取的字符串长度,如果为-1,代表全部读取完毕

    int len =0;

//使用一个输入流从buffer里把数据读取出来

    while( (len=inStream.read(buffer)) != -1 ){

//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度

        outStream.write(buffer,0, len);

}

//关闭输入流

    inStream.close();

//把outStream里的数据写入内存

    return outStream.toByteArray();

}

以上步骤就分别把富文本的普通批量上传了,可以看到文件夹里有复制过来上传的大量图片


富文本批量上传的功能也就实现了,其实其他2个富文本也可以用后台上传图片的方式处理,只是这2个富文本实现不了保留第三方复制过来的图文的格式。所以我最终选择了vue-html5-editor。欢迎大家投稿,第一次写文档,菜鸟程序员飞真顺献上。V:yqf822547775

你可能感兴趣的:(从第三方(秀米编辑器)复制粘贴图文,图片上传至本地文件夹,并在小程序端显示)