纯前端导出微信通信录到 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;
}

复制代码

参考文章

相关文章
相关标签/搜索