Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

导出微信通讯录到 Excel #14

Open
xiaoyu2er opened this issue Nov 14, 2018 · 0 comments
Open

导出微信通讯录到 Excel #14

xiaoyu2er opened this issue Nov 14, 2018 · 0 comments

Comments

@xiaoyu2er
Copy link
Owner

xiaoyu2er commented Nov 14, 2018

导出微信通讯录到 Excel

原文发自我的 github 博客

缘由

小 N 同学通讯录太多,希望可以导出到 Excel 中,网上大部分做法都需要安装软件或者还有自己整理数据,太麻烦。

我们来试一试可不可以通过前端的思路来解决这个问题。

思路

  1. 拿到通讯录
  2. 导出到 Excel

既然是前端工程师,那么最简单的方式就是登录微信 web 版, 直接去看微信活动通讯录的接口。

我们看一下

image

可以看到,由于微信后端返回数据中中文出现了乱码,暂且没有想好如何处理这些乱码。

但是界面中的中文确实正常的,我们看一下有没有其他别的方法呢?

image

通过看网页结构,我们发现这是一个用 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;
}

参考文章

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant