前言:

1,一次拉取调用最多拉取10000个关注者的OpenID,当公众号关注者数量超过10000时,可通过填写next_openid的值,从而多次拉取列表的方式来满足需求

2,获取OpenID列表后,要批量获取用户微信信息,最多支持一次拉取100条

3,处理Excel的jar包用的是jxl

4,导出过程中不要输出内容到控制台(System.out.println,我开始是输出了分页页码)。会导致运行时间延长很多;而且控制台会遗漏打印,让人以为有部分数据没有获取到,但其实导出到Excel表的数据是没有问题的

正文:

1,获取所有的OpenID

//获取用户列表
public static String USER_LIST_URL = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s&next_openid=%s";
//获取所有的openId
public static List<String> getAllOpenId(String appId)
{
List<String> openIds = getOpenIds("", appId);
logger.info(String.format("公众号人数:%s", openIds.size()));
return openIds;
} private static List<String> getOpenIds(String next_openid, String appId)
{
List<String> openIdList=new ArrayList<String>(); String accessToken = WeixinUtil.getAccessToken(appId);
String requestUrl = String.format(WxConfig.USER_LIST_URL, accessToken, next_openid); //拼接请求地址
JSONObject jsonObject = HttpRequest.httpRequest(requestUrl, "GET", null); //获取用户列表 if (null != jsonObject) {
try {
next_openid = jsonObject.getString("next_openid");
int count = jsonObject.getInt("count");
JSONObject openIdObject = jsonObject.getJSONObject("data"); if (count > 0) {
JSONArray openids = openIdObject.getJSONArray("openid");
List<String> temp_openIdList = JSONArray.toList(openids, new String(), new JsonConfig());
openIdList.addAll(temp_openIdList);
} if (StringUtils.isNotEmpty(next_openid)) {
List<String> list = getOpenIds(next_openid, appId);
openIdList.addAll(list);
}
} catch (Exception e) {
logger.info(String.format("获取用户列表失败 errcode:%s;errmsg:%s", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")));
}
}
return openIdList;
}

2,根据openId列表获取用户信息

//批量获取用户基本信息
public static String USER_LIST_INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=%s";
public static List<WxUserAll> getUserInfo(List<String> userOpenids, String appId)
{
List<WxUserAll> user_info_list = new ArrayList<WxUserAll>(); String accessToken = WeixinUtil.getAccessToken(appId);
String requestUrl = String.format(WxConfig.USER_LIST_INFO_URL, accessToken); //拼接请求地址 int total = userOpenids.size();
int temp = 100; //一次获取100
int page = 0; //当前页面
int count = 0; //总共获取多少次
int index = 0; if(total != 0){
if(total > temp){
count = total/100 + ((total % 100 > 0) ? 1 : 0);
}else{
count = 1;
} while (page < count) {
System.out.println("page="+page); List<Map> userList = new ArrayList<Map>();
index = (temp*(page+1)) > total ? total : (temp*(page+1)); for (int i = page*temp; i <index; i++)
{
String openid = userOpenids.get(i);
Map tUserMap = new HashMap<String, String>();
tUserMap.put("openid", openid);
tUserMap.put("lang", "zh_CN");
userList.add(tUserMap);
}
Map requestMap = new HashMap<String, List>();
requestMap.put("user_list", userList);
String tUserJSON = JSONObject.fromObject(requestMap).toString(); if(StringUtils.isNotEmpty(tUserJSON)){
JSONObject jsonObject = HttpRequest.httpRequest(requestUrl, "POST", tUserJSON); //获取用户列表
if(jsonObject != null){
JSONArray user_list = jsonObject.getJSONArray("user_info_list");
List<WxUserAll> temp_user_info_list = JSONArray.toList(user_list, new WxUserAll(), new JsonConfig());
user_info_list.addAll(temp_user_info_list);
}
page++;
}else{
break;
}
}
} return user_info_list;
}

3,jxl,jar包

<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>

4,导出数据到Excel,字段自己选择要哪些

import java.io.File;
import java.util.Date;
import java.util.List; import org.apache.commons.lang.StringUtils; import com.bf.base.utils.CalendarUtil;
import com.bf.wxChange.params.WxUserAll; import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook; public class SaveToExcel {
public static File saveToExcel(List<WxUserAll> userInfos){
File file=null;
try {
WritableWorkbook wwb = null; String fileName = "wxList.xls"; //创建可写入的Excel工作簿
file = new File(fileName); //以fileName为文件名来创建一个Workbook
wwb = Workbook.createWorkbook(file); // 创建工作表
WritableSheet ws = wwb.createSheet("wxList", );
ws.setColumnView(,);
ws.setColumnView(,);
ws.setColumnView(,);
ws.setColumnView(,);
ws.setColumnView(,);
ws.setColumnView(,); ws.mergeCells(,,,); //合并第一列第一行到第七列第一行的所有单元格
WritableFont font1= new WritableFont(WritableFont.TIMES,,WritableFont.BOLD);
WritableCellFormat format1=new WritableCellFormat(font1);
format1.setAlignment(jxl.format.Alignment.CENTRE);
Label top= new Label(, , "all user info",format1);
ws.addCell(top); //要插入到的Excel表格的行号,默认从0开始
Label label0 = new Label(, , "wxId");
Label label1 = new Label(, , "nickname");
Label label2 = new Label(, , "createTime");
Label label3 = new Label(, , "avatar");
Label label4 = new Label(, , "subscribe");
Label label5 = new Label(,, "wxUnionId");
ws.addCell(label0);
ws.addCell(label1);
ws.addCell(label2);
ws.addCell(label3);
ws.addCell(label4);
ws.addCell(label5); for (int i = ; i < userInfos.size(); i++) {
Label user0 = new Label(, i+, userInfos.get(i).getOpenid());
Label user1 = new Label(, i+, userInfos.get(i).getNickname());
String subscribeTime = userInfos.get(i).getSubscribe_time();
if (StringUtils.isNotEmpty(subscribeTime)) {
subscribeTime = CalendarUtil.DtoS(new Date(Long.parseLong(subscribeTime) * 1000L));
}
Label user2 = new Label(, i+, subscribeTime);
Label user3 = new Label(, i+, userInfos.get(i).getHeadimgurl());
Label user4 = new Label(, i+, userInfos.get(i).getSubscribe() == ? "" : "");
Label user5 = new Label(, i+, userInfos.get(i).getUnionid()); ws.addCell(user0);
ws.addCell(user1);
ws.addCell(user2);
ws.addCell(user3);
ws.addCell(user4);
ws.addCell(user5);
} wwb.write(); //写进文档
wwb.close(); //关闭Excel工作簿对象
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return file;
}
}

5,测试类

@RunWith(SpringRunner.class)
@SpringBootTest
public class SaveToExcelTest { private static String APP_ID = Config.JOINT_CARE_APP_NAME; @Test
public void ExcelTest() {
UserUtil.getAllOpenId(APP_ID);
} @Test
public void AllExcelTest() {
List<WxUserAll> allUserInfo = UserUtil.getUserInfo(UserUtil.getAllOpenId(APP_ID), APP_ID); if (!allUserInfo.isEmpty()) {
SaveToExcel.saveToExcel(allUserInfo);
}else {
System.out.println("目前暂无用户...");
}
}
}

6,其他代码

WxUserAll

public class WxUserAll {
private Integer subscribe; private String openid; private String nickname; private Integer sex; private String language; private String city; private String province; private String country; private String headimgurl; private String subscribe_time; private String unionid; private String remark; private Integer groupid; private List<String> tagid_list; private String subscribe_scene; private Integer qr_scene; private String qr_scene_str; @Override
public String toString() {
return "WxUserAll [subscribe=" + subscribe + ", openid=" + openid + ", nickname=" + nickname + ", sex=" + sex
+ ", language=" + language + ", city=" + city + ", province=" + province + ", country=" + country
+ ", headimgurl=" + headimgurl + ", subscribe_time=" + subscribe_time + ", unionid=" + unionid
+ ", remark=" + remark + ", groupid=" + groupid + ", tagid_list=" + tagid_list + ", subscribe_scene="
+ subscribe_scene + ", qr_scene=" + qr_scene + ", qr_scene_str=" + qr_scene_str + "]";
} public Integer getSubscribe() {
return subscribe;
} public void setSubscribe(Integer subscribe) {
this.subscribe = subscribe;
} public String getOpenid() {
return openid;
} public void setOpenid(String openid) {
this.openid = openid;
} public String getNickname() {
return nickname;
} public void setNickname(String nickname) {
this.nickname = nickname;
} public Integer getSex() {
return sex;
} public void setSex(Integer sex) {
this.sex = sex;
} public String getLanguage() {
return language;
} public void setLanguage(String language) {
this.language = language;
} public String getCity() {
return city;
} public void setCity(String city) {
this.city = city;
} public String getProvince() {
return province;
} public void setProvince(String province) {
this.province = province;
} public String getCountry() {
return country;
} public void setCountry(String country) {
this.country = country;
} public String getHeadimgurl() {
return headimgurl;
} public void setHeadimgurl(String headimgurl) {
this.headimgurl = headimgurl;
} public String getSubscribe_time() {
return subscribe_time;
} public void setSubscribe_time(String subscribe_time) {
this.subscribe_time = subscribe_time;
} public String getUnionid() {
return unionid;
} public void setUnionid(String unionid) {
this.unionid = unionid;
} public String getRemark() {
return remark;
} public void setRemark(String remark) {
this.remark = remark;
} public Integer getGroupid() {
return groupid;
} public void setGroupid(Integer groupid) {
this.groupid = groupid;
} public List<String> getTagid_list() {
return tagid_list;
} public void setTagid_list(List<String> tagid_list) {
this.tagid_list = tagid_list;
} public String getSubscribe_scene() {
return subscribe_scene;
} public void setSubscribe_scene(String subscribe_scene) {
this.subscribe_scene = subscribe_scene;
} public Integer getQr_scene() {
return qr_scene;
} public void setQr_scene(Integer qr_scene) {
this.qr_scene = qr_scene;
} public String getQr_scene_str() {
return qr_scene_str;
} public void setQr_scene_str(String qr_scene_str) {
this.qr_scene_str = qr_scene_str;
}
}

参考博客:

1,微信公众号开发之如何一键导出微信所有用户信息到Excel - 酷玩时刻 - 博客园 https://www.cnblogs.com/zyw-205520/p/5958560.html

【微信公众号开发】【13】批量导出公众号所有用户信息到Excel的更多相关文章

  1. 微信公众号开发之如何一键导出微信所有用户信息到Excel

    微信开发交流群:148540125 系列文章参考地址 极速开发微信公众号欢迎留言.转发.打赏 项目源码参考地址 点我点我--欢迎Start 极速开发微信公众号系列文章之如何一键导出微信所有用户信息到E ...

  2. 微信公众号开发之网页中及时获取当前用户Openid及注意事项

    目录 (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 (四)微信公众号开发之网页授权获取用户基本信息 (五)微信公众号开发之网页中及 ...

  3. Senparc.Weixin.MP SDK 微信公众平台开发教程(七):解决用户上下文(Session)问题

    从这篇文章中我们已经了解了微信公众平台消息传递的方式,这种方式有一个先天的缺陷:不同用户的请求都来自同一个微信服务器,这使得常规的Session无法使用(始终面对同一个请求对象,况且还有对方服务器Co ...

  4. C#微信公众号开发之网页授权oauth2.0获取用户基本信息(一)

    咨询 请加 QQ::QQ群: 在微信里面,非认证的公众号账号,只能通过在微信回复菜单单击等事件获取openid,但是认证的公众账号(之前认证的订阅号是不可以的,现在新开放了政府媒体机构的认证订阅号)可 ...

  5. 转载收藏之用 - 微信公众平台开发教程(七):解决用户上下文(Session)问题

    从这篇文章中我们已经了解了微信公众平台消息传递的方式,这种方式有一个先天的缺陷:不同用户的请求都来自同一个微信服务器,这使得常规的Session无法使用(始终面对同一个请求对象,况且还有对方服务器Co ...

  6. .NET微信开发通过Access Token和OpenID获取用户信息

    本文介绍如何获得微信公众平台关注用户的基本信息,包括昵称.头像.性别.国家.省份.城市.语言. 本文的方法将囊括订阅号和服务号以及自定义菜单各种场景,无论是否有高级接口权限,都有办法来获得用户基本信息 ...

  7. Azure PowerShell (15) 批量导出Azure ASM/ARM VM信息

    <Windows Azure Platform 系列文章目录> 客户又提出新的需求,需要知道所有订阅下的虚拟机数量.运行情况等信息. 我花了点时间,写了一个PowerShell脚本,发布到 ...

  8. C#微信公众号开发-高级接口-之网页授权oauth2.0获取用户基本信息(二)

    C#微信公众号开发之网页授权oauth2.0获取用户基本信息(一) 中讲解了如果通过微信授权2.0snsapi_base获取已经关注用户的基本信息,然而很多情况下我们经常需要获取非关注用户的信息,方法 ...

  9. 微信公众号开发笔记(C#)

    这篇文章还不错,使用  .net , 对微信用户的想公众号发送的文字进行回复.比较简单,自己可以修改更复杂的回复. 微信公众号开发笔记(C#) 原文地址 需求分析 根据用户在微信上发送至价值中国公众号 ...

随机推荐

  1. 题解——洛谷P2781 传教(线段树)

    可以说是数据结构学傻了的典型案例了 昨天跳到这题上 然后思考了一下 噫!好!线段树裸题 然后打完板子,发现\(  n \le 10^9 \) 显然线段树直接做不太行 然后这题又只有普及的难度 然后我就 ...

  2. (转载)Windows下小狼毫输入法(Rime)的安装与配置(含导入搜狗词库)

    div id="cnblogs_post_body" class="blogpost-body"> 最近彻底烦透了搜狗拼音输入法的各种流氓行为,自动升级不 ...

  3. 操作 frames 框架下的 dom 内容。

    2016-12-30 框架名: var obj=$(window.frames["wangpan"].document).find("a[menu=download_on ...

  4. 【六】php 错误异常处理

    错误异常处理 概念:代码在try代码块被调用执行,catch代码块捕获异常 异常需要手动抛出 throw new Exception (‘message’,code) throw将出发异常处理机制 在 ...

  5. Spring boot @Scheduled(cron = "* * * * * *") cron表达式详解

    //@Scheduled(cron = "0 0/15 * * * ?") //每15分钟触发一次 //@Scheduled(cron = "5/10 * * * * ? ...

  6. CentOS6.X、7.X下Jenkins的安装及使用

    一.相关概念 1.1 Jenkins概念: Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台.这是一个免费的源代码,可以处理任何类型的构建或持续集成.集成Jenk ...

  7. ABP捕捉异常错误代码

    在服务层或者CORE层  随便哪里都可以  创建一个捕捉异常的文件夹  里面写一个LonsidException类 继承后面的接口  然后重写继承的方法  这样在ABP项目运行阶段  无论在哪里出现异 ...

  8. 力扣(LeetCode) 849. 到最近的人的最大距离

    在一排座位( seats)中,1 代表有人坐在座位上,0 代表座位上是空的. 至少有一个空座位,且至少有一人坐在座位上. 亚历克斯希望坐在一个能够使他与离他最近的人之间的距离达到最大化的座位上. 返回 ...

  9. Selenium WebDriver Api 知识梳理

    之前一直没有系统的梳理WebDriver Api的相关知识,今天借此机会整理一下. 1.页面元素定位 1.1.8种常用定位方法 # id定位 driver.find_element_by_id() # ...

  10. Asp.net core 学习笔记 ( User Secrets )

    参考 : http://cnblogs.com/nianming/p/7068253.html https://docs.microsoft.com/en-us/aspnet/core/securit ...