原文
演示地址
你可以訪問下面的地址體驗每個demo
https://fairyever.github.io/excel-to-image-demo/
需求
前些天公司要求做一個可以在輸入框粘貼Excel表格的控件,也算是折騰了半天時間缩筛,寫下來做個記錄
具體效果可以參考京東客服聊天界面够滑,在輸入框粘貼表格后會生成圖片發(fā)送出去
實現(xiàn)步驟
具體當時怎么栽的坑就不具體說了,下面只是系統(tǒng)的演示一遍步驟
以下演示都是在這樣的一個輸入框中進行:
<div class="input-group ma-b-10">
<span class="input-group-addon" id="basic-addon3">在這里粘貼Excel表格</span>
<input ref="input" type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
</div>
使用了 VUE
和 bootstrap4
以及 HTML2canvas
測試表格
測試環(huán)境
windows
瀏覽器環(huán)境 Chrome | win10 in Parallels Desktop
mac
瀏覽器環(huán)境 Chrome | macOS Sierra 10.12.4
剪貼板里有什么
代碼
省略了部分不重要的內容
CDN庫
<link rel="stylesheet" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<script src="https://unpkg.com/vue"></script>
HTML
<div class="container" id="app">
<h1>檢查值類型</h1>
<div class="input-group ma-b-10">
<span class="input-group-addon" id="basic-addon3">在這里粘貼Excel表格</span>
<input ref="input" type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
</div>
<p><small>結果在控制臺打印</small></p>
</div>
JavaScript
var vm = new Vue({
el: '#app',
mounted: function() {
this.$refs.input.addEventListener("paste",
function(e) {
if (! (e.clipboardData && e.clipboardData.items)) {
return;
}
for (var i = 0; i < e.clipboardData.items.length; i++) {
console.log(e.clipboardData.items[i].type);
}
});
}
結果
mac
text/plain
text/html
text/rtf
image/png
windows
text/plain
text/rtf
image/png
分析
可見在 windows
環(huán)境下古毛,剪切板里的內容少了一個 text/html
為什么?
目前我也不知道都许。
檢查獲取到的實際值
代碼
for (var i = 0; i < e.clipboardData.items.length; i++) {
var item = e.clipboardData.items[i]
if (item.kind === "string") {
item.getAsString(function (str) {
console.log(str);
})
}
}
結果
text/plain
純文本
姓名 年齡 職業(yè) email 張三 20 不詳 不詳 李四 21 不詳 不詳 王五 22 不詳 不詳
text/html
HTML字符串
<html xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<meta name=ProgId content=Excel.Sheet>
<meta name=Generator content="Microsoft Excel 15">
<link id=Main-File rel=Main-File
href="file://localhost/Users/liyang/Library/Group%20Containers/UBF8T346G9.Office/msoclip1/01/clip.htm">
... 省略 ...
</tr>
<tr height=35 style='mso-height-source:userset;height:26.0pt'>
<td height=35 class=xl64 style='height:26.0pt;border-top:none'>王五</td>
<td class=xl65 style='border-top:none;border-left:none'>22</td>
<td class=xl65 style='border-top:none;border-left:none'>不詳</td>
<td class=xl65 style='border-top:none;border-left:none'>不詳</td>
</tr>
<!--EndFragment-->
</table>
</body>
</html>
text/rtf
編碼后的文本
{\rtf1\mac \ansicpg10008
{\fonttbl{\f0\fnil \fcharset134 ??ì?;}{\f1\fnil \fcharset134{\f16\fnil
......
image/png
在后面的測試中可以得到這是一個圖片文件稻薇,但不是一個圖片對象,更像文件選擇得到的文件
// 控制臺打印為空
嘗試顯示 text/html 類型的數(shù)據(jù)
代碼
HTML
<div class="input-group ma-b-10">
<span class="input-group-addon" id="basic-addon3">在這里粘貼Excel表格</span>
<input ref="input" type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
</div>
<div class="card ma-b-10">
<div class="card-body">
<h4 class="card-title">
嘗試使用<code>text/html</code>類型數(shù)據(jù)
</h4>
<h6 class="card-subtitle mb-2 text-muted">
如果可以獲取到數(shù)據(jù)胶征,將會在這里顯示結果
</h6>
<template v-if="tempData">
<div class="form-group">
<label for="exampleFormControlTextarea1">數(shù)據(jù)源碼</label>
<textarea
class="form-control"
id="exampleFormControlTextarea1"
rows="3"
v-model="tempData">
</textarea>
</div>
<div ref="tempGroup" v-html="tempData"></div>
</template>
</div>
</div>
JavaScript
var vm = new Vue({
el: '#app',
data: {
tempData: ''
},
mounted: function () {
var _this = this
this.$refs.input.addEventListener("paste", function (e){
if ( !(e.clipboardData && e.clipboardData.items) ) {
return ;
}
if (e.clipboardData.items[1].type === 'text/html') {
e.clipboardData.items[1].getAsString(function(str){
_this.tempData = str
})
}
});
}
})
結果
mac
windows
結論
text/html
類型的數(shù)據(jù)在mac上是可用的(比如用在使用electron開發(fā)的macOS應用中)塞椎,但是這不適用于windows平臺
使用text/html類型的數(shù)據(jù)生成圖片
更進一步,既然在mac上可以使用 text/html
類型的數(shù)據(jù)睛低,那就嘗試使用這個數(shù)據(jù)生成可以上傳至服務器的圖片資源
代碼
新引入了一個庫
<script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js"></script>
HTML比較長忱屑,請訪問倉庫查看源碼
JavaScript關鍵部分
var _this = this
this.$refs.input.addEventListener("paste", function (e){
if ( !(e.clipboardData && e.clipboardData.items) ) {
return ;
}
if (e.clipboardData.items[1].type === 'text/html') {
e.clipboardData.items[1].getAsString(function(str){
_this.tempData = str
Vue.nextTick(function(){
html2canvas(_this.$refs.tempGroup, {
onrendered: function(canvas) {
_this.$refs.canvasGroup.appendChild(canvas)
_this.base64 = canvas.toDataURL()
}
})
})
})
}
})
結果(mac)
到此為止在mac上一切順利蹬敲!,下面我們嘗試使用mac和windows共有的數(shù)據(jù)類型進行解析
使用image/png類型的數(shù)據(jù)生成圖片
代碼
注意莺戒,這種方式不需要 html2canvas
HTML比較長伴嗡,請訪問倉庫查看源碼
JavaScript關鍵部分
for (var i = 0; i < e.clipboardData.items.length; i++) {
if (e.clipboardData.items[i].type === 'image/png'){
var pasteFile = e.clipboardData.items[i].getAsFile();
var reader = new FileReader();
reader.readAsDataURL(pasteFile);
reader.onload=function(e){
_this.base64 = this.result;
}
}
}
結果
mac
windows
總結
使用 image/png
數(shù)據(jù)是可行的,而且這種方式相較于 html2canvas
還有一個優(yōu)點就是即使表格尺寸超過了一屏的大小(寬度和高度都可以)从铲,仍然可以很好的生成base64圖片
所有源碼請移至倉庫
end