你能夠訪問下面的地址體驗每一個demohtml
https://fairyever.github.io/excel-to-image-demo/vue
前些天公司要求作一個能夠在輸入框粘貼Excel表格的控件,也算是折騰了半天時間,寫下來作個記錄git
具體效果能夠參考京東客服聊天界面,在輸入框粘貼表格後會生成圖片發送出去github
具體當時怎麼栽的坑就不具體說了,下面只是系統的演示一遍步驟bootstrap
如下演示都是在這樣的一個輸入框中進行:canvas
<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
windows
瀏覽器環境 Chrome | win10 in Parallels Desktop
瀏覽器
瀏覽器環境 Chrome | macOS Sierra 10.12.4
服務器
省略了部分不重要的內容
CDN庫
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" 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); } }); }
text/plain text/html text/rtf image/png
text/plain text/rtf image/png
可見在 windows
環境下,剪切板裏的內容少了一個 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); }) } }
純文本
姓名 年齡 職業 email 張三 20 不詳 不詳 李四 21 不詳 不詳 王五 22 不詳 不詳
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>
編碼後的文本
{\rtf1\mac \ansicpg10008 {\fonttbl{\f0\fnil \fcharset134 ËÎÌå;}{\f1\fnil \fcharset134{\f16\fnil ......
在後面的測試中能夠獲得這是一個圖片文件,但不是一個圖片對象,更像文件選擇獲得的文件
// 控制檯打印爲空
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>類型數據 </h4> <h6 class="card-subtitle mb-2 text-muted"> 若是能夠獲取到數據,將會在這裏顯示結果 </h6> <template v-if="tempData"> <div class="form-group"> <label for="exampleFormControlTextarea1">數據源碼</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 }) } }); } })
text/html
類型的數據在mac上是可用的(好比用在使用electron開發的macOS應用中),可是這不適用於windows平臺
更進一步,既然在mac上能夠使用 text/html
類型的數據,那就嘗試使用這個數據生成能夠上傳至服務器的圖片資源
新引入了一個庫
<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和windows共有的數據類型進行解析
注意,這種方式不須要 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; } } }
使用 image/png
數據是可行的,並且這種方式相較於 html2canvas
還有一個優勢就是即便表格尺寸超過了一屏的大小(寬度和高度均可以),仍然能夠很好的生成base64圖片
全部源碼請移至倉庫
end