純前端導出微信通信錄到 Excel

原文發自個人 github 博客javascript

原因

小 N 同窗通信錄太多,但願能夠導出到 Excel 中,網上大部分作法都須要安裝軟件或者還有本身整理數據,太麻煩。前端

咱們來試一試可不能夠經過前端的思路來解決這個問題。java

思路

  1. 拿到通信錄
  2. 導出到 Excel

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

咱們看一下angularjs

能夠看到,因爲微信後端返回數據中中文出現了亂碼,暫且沒有想好如何處理這些亂碼。github

可是界面中的中文確實正常的,咱們看一下有沒有其餘別的方法呢?web

經過看網頁結構,咱們發現這是一個用 angularjs 1.x 編寫的網頁應用(出現了ng-style ng-repeat等關鍵詞)json

咱們知道 angularjs 中的雙向綁定,通常變量都會掛在 scope 上後端

既然全部的聯繫人都出如今了 $('.scroll-wrapper .J_ContactScrollBody')中,那咱們看看這個列表關聯的 scope 中是否含有這些信息bash

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

複製代碼

參考文章

相關文章
相關標籤/搜索