1. 程式人生 > >純前端匯出微信通訊錄到 Excel

純前端匯出微信通訊錄到 Excel

原文發自我的 github 部落格

緣由

小 N 同學通訊錄太多,希望可以匯出到 Excel 中,網上大部分做法都需要安裝軟體或者還有自己整理資料,太麻煩。

我們來試一試可不可以通過前端的思路來解決這個問題。

思路

  1. 拿到通訊錄
  2. 匯出到 Excel

既然是前端工程師,那麼最簡單的方式就是登入微信 web 版, 直接去看微信活動通訊錄的介面。

我們看一下

可以看到,由於微信後端返回資料中中文出現了亂碼,暫且沒有想好如何處理這些亂碼。

但是介面中的中文確實正常的,我們看一下有沒有其他別的方法呢?

通過看網頁結構,我們發現這是一個用 angularjs 1.x 編寫的網頁應用(出現了ng-style

ng-repeat等關鍵詞)

我們知道 angularjs 中的雙向繫結,一般變數都會掛在 scope 上

既然所有的聯絡人都出現在了 $('.scroll-wrapper .J_ContactScrollBody')中,那我們看看這個列表關聯的 scope 中是否含有這些資訊

var scope = angular.element($('.scroll-wrapper .J_ContactScrollBody')).scope();
var allContacts = scope.allContacts;
複製程式碼

果不其然,在 $('.scroll-wrapper .J_ContactScrollBody')

關聯的 scope 上掛載有 allContracts

(其實在觀察的過程中,發現微信的工程師把所有的聯絡人資訊放到了 window._contracts 上了,這也是一種方法。)

拿到資料之後接下來就是匯出到 Excel 了,這裡選用了 js-xlsx 庫,其中的細節不再贅述

直接看一下原始碼

原始碼+註釋

// 點選通訊錄 tab
$('.web_wechat_tab_friends').click();

// 等待幾秒鐘...

// 獲取通訊錄列表
// 方法一
var scope = angular.element($('.scroll-wrapper .J_ContactScrollBody'
)).scope(); var allContacts = scope.allContacts; // 方法二 // var allContacts = Object.keys(window._contacts).map(k => window._contacts[k]); // 過濾真實的使用者 var contacts = allContacts.filter(c => c.UserName); // 下載 excel 指令碼 loadScript('https://oss.sheetjs.com/js-xlsx/xlsx.full.min.js') .then(() => { console.log('download js-xlsx successful '); var config = {bookType: 'xlsx', bookSST: false, type: 'binary'};//這裡的資料是用來定義匯出的格式型別 var wb = {SheetNames: ['Sheet1'], Sheets: {}, Props: {}}; // 通過json_to_sheet 轉成單頁(Sheet)資料 wb.Sheets['Sheet1'] = XLSX.utils.json_to_sheet(formatContacts(contacts)); var fileName = '微信通訊錄' + '.' + (config.bookType == "biff2" ? "xls" : config.bookType); saveAs(new Blob([s2ab(XLSX.write(wb, config))], {type: 'application/octet-stream'}), fileName); }); // ---- helper functions ----- /** * 將 contacts 轉化成你需要的格式 * 這裡可以任意發揮 * @param contacts * @returns {*} */ function formatContacts(contacts) { return contacts.map(({NickName, Sex, RemarkName}) => { return { '暱稱': NickName, '備註': RemarkName } }) } /** * 載入 script * @param url * @returns {Promise} */ function loadScript(url) { return new Promise((resolve) => { var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = 'text/javascript'; script.onload = resolve; script.src = url; head.appendChild(script); }) } /** * 下載檔案 * @param obj * @param fileName */ function saveAs(obj, fileName) { var a = document.createElement('a'); a.download = fileName || '下載'; a.href = URL.createObjectURL(obj); a.click(); // 模擬點選實現下載 setTimeout(function () { URL.revokeObjectURL(obj); // 釋放 objectURL }, 100); } /** * 字串轉字元流 * @param s * @returns {ArrayBuffer} */ function s2ab(s) { var buf = new ArrayBuffer(s.length); var view = new Uint8Array(buf); for (var i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF; return buf; } 複製程式碼

參考文章

其他

如果你覺得我寫的文章對你有幫助,歡迎讚賞,謝謝支援~

歡迎同學加入『前端技術交流群』,加下面兩個同學的微信(不用重複加),回覆『小魚二前端』即可進群。