從第三方(秀米編輯器)復(fù)制粘貼圖文姐军,圖片上傳至本地文件夾,并在小程序端顯示

????????接到這個需求的時候有點詫異和迷茫尖淘,后面經(jīng)過自己的一步一步摸索終于實現(xiàn)了這個讓人頭疼的需求奕锌。客戶需求:從第三方(秀米編輯器)復(fù)制粘貼圖文保留圖文樣式村生,并且圖片批量上傳至本地文件夾惊暴,并在小程序端顯示。前端是vue趁桃,后端是java語言辽话。

? ? ? ? 這個功能是實現(xiàn)我試了3個富文本,分別是quillEditor卫病,tinymce油啤,vue-html5-editor。

????????最后用vue-html5-editor這個富文本實現(xiàn)了蟀苛,vue-html5-editor富文本從第三方復(fù)制過來時可以保留第三方的所有樣式益咬,包括文字樣式,圖片樣式帜平。思路:復(fù)制過來圖片批量上傳是在后臺(JAVA)進行處理的幽告,后臺可以直接用正則表達(dá)式截取網(wǎng)絡(luò)圖片或者Base64圖片上傳至本地文件夾然后顯示在小程序端比庄。

? ? ? ? 先介紹一下quillEditor這個富文本蜕劝,quillEditor該富文本只能實現(xiàn)單個圖片上傳酪惭,從第三方復(fù)制黏貼過來上傳無效液南,親測鹃唯。

? ??????tinymce可以使用powerpaste(收費)插件進行圖片批量上傳禀晓,但是我公司做的是一個小項目达椰,老板也拒絕付費去購買該插件友绝。網(wǎng)上其實也可以找到powerpaste插件,可以去網(wǎng)盤直接下載芋绸,但是又遇到問題從網(wǎng)盤下載的powerpaste(不收費插件)配Tinymce4.x就會很多地方不適應(yīng)的地方媒殉,該版本的兼容性肯定不行,會導(dǎo)致圖片復(fù)制過來是空白的問題摔敛,然后又放棄了這個富文本廷蓉。

? ??????vue-html5-editor富文本雖然是個html5的富文本,但是從第三方復(fù)制過來的圖文是可以保留樣式的马昙,然后百度搜索該富文本是否有批量上傳圖片的屬性桃犬,根本沒有找到,然后自己轉(zhuǎn)換了想法行楞,決定在前端點保存時把圖片全部都都轉(zhuǎn)成base64格式攒暇,轉(zhuǎn)完之后存進數(shù)據(jù)庫里發(fā)現(xiàn)數(shù)據(jù)量太大(5M,10M)子房,在小程序端渲染速率太慢了形用。這個想法也放棄了。

? ? ? ? 最后靈機一動發(fā)現(xiàn)可以把網(wǎng)絡(luò)圖片或者bsae64的圖片直接在后臺進行上傳证杭。不多說了田度,上代碼。

?步驟一: 前端(vue)

在頁面引入

<vue-html5-editor class="coursesuggest" :content="activityForm.activityContent" @change="updateData"></vue-html5-editor>

步驟二:在main.js引入

let opt = {

// 全局組件名稱解愤,使用new VueHtml5Editor(options)時該選項無效

? name:"vue-html5-editor",

// 是否顯示模塊名稱镇饺,開啟的話會在工具欄的圖標(biāo)后臺直接顯示名稱

? showModuleName:true,

// 自定義各個圖標(biāo)的class,默認(rèn)使用的是font-awesome提供的圖標(biāo)

? 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: {

// 文件最大體積送讲,單位字節(jié)

? ? sizeLimit:512 *1024 *10,

// 上傳參數(shù),默認(rèn)把圖片轉(zhuǎn)為base64而不上傳

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

? ? upload: {

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

? ? ? url:null,

headers: {

},

params: {

},

fieldName:'file'

? ? },

// 壓縮參數(shù),默認(rèn)使用localResizeIMG進行壓縮,設(shè)置為null禁止壓縮

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

? ? compress: {

width:300,

height:null,

quality:80

? ? },

// 響應(yīng)數(shù)據(jù)處理,最終返回圖片鏈接

? ? 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)

}

}

},

// 語言奸笤,內(nèi)建的有英文(en-us)和中文(zh-cn)

? language:"zh-cn",

// 自定義語言

? i18n: {

"zh-cn": {

"align":"對齊方式",

"image":"圖片",

"list":"列表",

"link":"鏈接",

"unlink":"去除鏈接",

"table":"表格",

"font":"文字",

"full screen":"全屏",

"text":"排版",

"eraser":"格式清除",

"info":"關(guān)于",

"color":"顏色",

"please enter a url":"請輸入地址",

"create link":"創(chuàng)建鏈接",

"bold":"加粗",

"italic":"傾斜",

"underline":"下劃線",

"strike through":"刪除線",

"subscript":"上標(biāo)",

"superscript":"下標(biāo)",

"heading":"標(biāo)題",

"font name":"字體",

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

"left justify":"左對齊",

"center justify":"居中",

"right justify":"右對齊",

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

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

"fore color":"前景色",

"background color":"背景色",

"row count":"行數(shù)",

"column count":"列數(shù)",

"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);

步驟三:前臺頁面點提交后把富文本的全部數(shù)據(jù)都傳到后臺监右,后臺代碼如下

String regex ="src=['\"](.*?)['\"]";//正則表達(dá)式來匹配src屬性

Pattern pattern = Pattern.compile(regex);//使用正則獲取富文本里的所有圖片

Matcher m = pattern.matcher(activity.getActivityContent());//傳入富文本內(nèi)容進行格式化

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);

}

//復(fù)制上傳是網(wǎng)絡(luò)圖片

? ? else {

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

? ? }

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

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

}

m.appendTail(sb);

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


上面分別把base64的圖片和網(wǎng)絡(luò)圖片上傳到了本地,

base64上傳代碼如下

/**

* base64轉(zhuǎn)圖片上傳至本地文件夾

* @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) {

//調(diào)整異常數(shù)據(jù)

? ? ? ? if (b[i] <0) {

b[i] +=256;

}

}

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

String filedata = dates();

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

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

//new一個文件對象用來保存圖片魄宏,默認(rèn)保存當(dāng)前工程根目錄

? ? 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;

}


網(wǎng)絡(luò)圖片上傳代碼如下:

/**

* 秀米圖片轉(zhuǎn)圖片上傳至本地文件夾

* @param imgOldUrl

* @return

*/

public String richImage(String imgOldUrl)throws Exception{

//new一個URL對象

? ? URL url =new URL(imgOldUrl);

//打開鏈接

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

//設(shè)置請求方式為"GET"

? ? conn.setRequestMethod("GET");

//超時響應(yīng)時間為5秒

? ? conn.setConnectTimeout(5 *1000);

//通過輸入流獲取圖片數(shù)據(jù)

? ? InputStream inStream = conn.getInputStream();

//得到圖片的二進制數(shù)據(jù)秸侣,以二進制封裝得到數(shù)據(jù)存筏,具有通用性

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

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

String filedata = dates();

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

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

//new一個文件對象用來保存圖片宠互,默認(rèn)保存當(dāng)前工程根目錄

? ? 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);

//創(chuàng)建輸出流

? ? FileOutputStream outStream =new FileOutputStream(imageFile1);

//寫入數(shù)據(jù)

? ? outStream.write(data);

//關(guān)閉輸出流

? ? 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();

//創(chuàng)建一個Buffer字符串

? ? byte[] buffer =new byte[1024];

//每次讀取的字符串長度,如果為-1椭坚,代表全部讀取完畢

? ? int len =0;

//使用一個輸入流從buffer里把數(shù)據(jù)讀取出來

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

//用輸出流往buffer里寫入數(shù)據(jù)予跌,中間參數(shù)代表從哪個位置開始讀,len代表讀取的長度

? ? ? ? outStream.write(buffer,0, len);

}

//關(guān)閉輸入流

? ? inStream.close();

//把outStream里的數(shù)據(jù)寫入內(nèi)存

? ? return outStream.toByteArray();

}

以上步驟就分別把富文本的普通批量上傳了善茎,可以看到文件夾里有復(fù)制過來上傳的大量圖片


富文本批量上傳的功能也就實現(xiàn)了券册,其實其他2個富文本也可以用后臺上傳圖片的方式處理,只是這2個富文本實現(xiàn)不了保留第三方復(fù)制過來的圖文的格式。所以我最終選擇了vue-html5-editor烁焙。歡迎大家投稿航邢,第一次寫簡書文檔,菜鳥程序員飛真順獻上骄蝇。V:yqf822547775

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膳殷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子九火,更是在濱河造成了極大的恐慌赚窃,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岔激,死亡現(xiàn)場離奇詭異勒极,居然都是意外死亡,警方通過查閱死者的電腦和手機虑鼎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門辱匿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人炫彩,你說我怎么就攤上這事掀鹅。” “怎么了媒楼?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵乐尊,是天一觀的道長。 經(jīng)常有香客問我划址,道長扔嵌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任夺颤,我火速辦了婚禮痢缎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘世澜。我一直安慰自己独旷,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布寥裂。 她就那樣靜靜地躺著嵌洼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪封恰。 梳的紋絲不亂的頭發(fā)上麻养,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天,我揣著相機與錄音诺舔,去河邊找鬼鳖昌。 笑死备畦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的许昨。 我是一名探鬼主播懂盐,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼糕档!你這毒婦竟也來了允粤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤翼岁,失蹤者是張志新(化名)和其女友劉穎类垫,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體琅坡,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡悉患,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了榆俺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片售躁。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖茴晋,靈堂內(nèi)的尸體忽然破棺而出陪捷,到底是詐尸還是另有隱情,我是刑警寧澤诺擅,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布市袖,位于F島的核電站,受9級特大地震影響烁涌,放射性物質(zhì)發(fā)生泄漏苍碟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一撮执、第九天 我趴在偏房一處隱蔽的房頂上張望微峰。 院中可真熱鬧,春花似錦抒钱、人聲如沸蜓肆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仗扬。三九已至,卻和暖如春瑞信,著一層夾襖步出監(jiān)牢的瞬間厉颤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工凡简, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留逼友,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓秤涩,卻偏偏與公主長得像帜乞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子筐眷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348