企微群机器人推送文本+Excel

您所在的位置:网站首页 excel文件怎样发送到微信群里 企微群机器人推送文本+Excel

企微群机器人推送文本+Excel

2024-06-09 03:46| 来源: 网络整理| 查看: 265

例如,企微群定时推送:内容+表格

群机器人:学校基本信息:

[一个记录学校基本信息的excel表]

 excel表简单类似:

准备肯定先企微群创建一个机器人,获取到群webhook备用;

简易步骤比较简单,先分别获取老师、学生、职工的list信息->再把列表转化为excel表->推送消息

 一、推送工具类;(isNotBank之类的判空方法,可以自行重写)

import lombok.extern.slf4j.Slf4j; import okhttp3.*; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; /** * @author yrl * @date 2023/7/5 15:29 */ @Slf4j public class WxPushUtil { /** * 企业微信机器人api地址与key;webhook 截取 */ private final static String WECHAT_API_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/"; private final static String WECHAT_API_KEY = "xxxxx-xxx-xxx-xxxxxxxxxxxxxxxxx"; /** * 学生列表数据转化为 excel * * @param wb Workbook * @param student 学生 * @param dest 首栏提示 默认可空 * @param pageName 底部分页表名称 */ public static boolean studentFileBuild(HSSFWorkbook wb, List student, String dest, String pageName) { // if (student == null || student.size() < 0) { return false; } //表头字段,与对象一致 String[] titleArray = new String[]{"学生姓名", "年龄", "性别", "班级"}; String[] fieldArray = new String[]{"studentName", "age", "sex", "class"}; List list = new ArrayList(); for (Student s : student) { //转成map Map map = BeanUtils.beanToMap(s); list.add(map); } if (list.size() > 0) { //数据组合 到HSSFWorkbook ExcelUtil.buildExcel(list, wb, pageName, titleArray, fieldArray, dest); return true; } return false; } /** * 老师 数据转化为excel构建 * * @param wb Workbook * @param teacher 老师 * @param dest 首栏提示 默认可空 * @param pageName 底部分页表名称 */ public static boolean teacherFileBuild(HSSFWorkbook wb, List teacher, String dest, String pageName) { // if (teacher == null || teacher.size() < 0) { return false; } //表头字段,与对象一致 String[] titleArray = new String[]{"工号", "姓名", "性别", "职位"}; String[] fieldArray = new String[]{"number", "name", "sex", "lev"}; List list = new ArrayList(); for (Teacher s : teacher) { //转成map Map map = BeanUtils.beanToMap(s); list.add(map); } if (list.size() > 0) { //数据组合 到HSSFWorkbook ExcelUtil.buildExcel(list, wb, pageName, titleArray, fieldArray, dest); return true; } return false; } /** * 发送文件消息,需要先将文件上传到企业微信临时素材,再根据获取的media_id调用群机器人 * * @param file 需要发送的文件 * @param text 发送附件的同时需要发送文字内容 * @param phoneList 需要@的群成员手机号 */ public static void sendFileMsg(File file, String text, List phoneList) { // 构造RequestBody对象,用来携带要提交的数据;需要指定MediaType,用于描述请求/响应 body 的内容类型 MediaType contentType = MediaType.parse("application/form-data; boundary"); RequestBody body = RequestBody.create(contentType, file); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", file.getName(), body) .build(); try { //获取推送的群id,如果多个,推送多个 // 上传到临时素材 String mediaUrl = WECHAT_API_URL + "upload_media?type=file&key=" + WECHAT_API_KEY; log.debug("将文件{}上传到临时素材:{}", file.getName(), mediaUrl); String respMsg = okHttp(requestBody, mediaUrl); log.debug("将文件{}上传到临时素材:{}, {}", file.getName(), mediaUrl, respMsg); // 获取临时素材id JSONObject result = JSONUtil.parseObj(respMsg); String mediaId = result.getStr("media_id"); if (U.isNotBlank(text)) { JSONObject textJson = new JSONObject(); textJson.set("content", text); JSONObject reqBody = new JSONObject(); //先推文本 reqBody.set("msgtype", "text"); reqBody.set("text", textJson); //"mentioned_mobile_list":["13800001111","@all"] if (A.isNotEmpty(phoneList)) { System.out.println("推送的手机号:" + phoneList); reqBody.set("mentioned_mobile_list", phoneList); } // 调用群机器人发送消息 callWeChatBot(reqBody.toString(), WECHAT_API_KEY); } JSONObject fileJson = new JSONObject(); fileJson.set("media_id", mediaId); JSONObject reqBody = new JSONObject(); //再推文件 reqBody.set("msgtype", "file"); reqBody.set("file", fileJson); reqBody.set("safe", 0); // 再调用群机器人发送文件消息 callWeChatBot(reqBody.toString(), WECHAT_API_KEY); } catch (Exception e) { log.error("文件推送异常:{}", file.getName(), e); } } /** * @param body 携带需要提交的数据(后续迁移) * @param url 请求地址 * @throws Exception 异常 */ private static String okHttp(RequestBody body, String url) throws Exception { // 构造和配置OkHttpClient OkHttpClient client = new OkHttpClient.Builder() // 设置连接超时时间 .connectTimeout(10, TimeUnit.SECONDS) // 设置读取超时时间 .readTimeout(20, TimeUnit.SECONDS) .build(); // 构造Request对象 Request request = new Request.Builder() .url(url) .post(body) // 响应消息不缓存 .addHeader("cache-control", "no-cache") .build(); // 构建Call对象,通过Call对象的execute()方法提交异步请求 Response response = client.newCall(request).execute(); // 请求结果处理 assert response.body() != null; byte[] datas = response.body().bytes(); return new String(datas); } /** * 调用群机器人 * * @param reqBody 接口请求参数 * @throws Exception 异常 */ private static void callWeChatBot(String reqBody, String key) throws Exception { log.debug("调用群机器人:{}", reqBody); // 构造RequestBody对象,用来携带要提交的数据;需要指定MediaType,用于描述请求/响应 body 的内容类型 okhttp3.MediaType contentType = okhttp3.MediaType.parse("application/json; charset=utf-8"); RequestBody body = RequestBody.create(contentType, reqBody); String botUrl = WECHAT_API_URL + "send?key=" + key; // 调用群机器人 String respMsg = okHttp(body, botUrl); JSONObject result = JSONUtil.parseObj(respMsg); if ("0".equals(result.getStr("errcode"))) { log.debug("调用群机器人发送消息成功, reqBody: {}, respMsg : {}", reqBody, respMsg); } else { log.error("调用群机器人发送消息失败, reqBody: {}, respMsg : {}", reqBody, respMsg); } } }

二、EXCEL工具类(list转化等)有些方法可能用不到

import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; /** * Excel工具类 */ public class ExcelUtil { public Class clazz; public ExcelUtil(Class clazz) { this.clazz = clazz; } /** * 读取Excel内容转为List */ public List importExcel(MultipartFile file) throws Exception { return importExcel(StringUtils.EMPTY, file); } /** * 读取Excel内容转为List */ public List importExcel(String sheetName, MultipartFile file) throws Exception { U.assertException(U.isBlank(file), "上传的文件为空"); //获取文件名 String fileName = file.getOriginalFilename(); U.assertException(!(fileName.endsWith(".xls") || fileName.endsWith(".xlsx")), "请选择Excel文件上传"); // List list = new ArrayList(); Workbook workbook = WorkbookFactory.create(file.getInputStream()); Sheet sheet; if (StringUtils.isNotEmpty(sheetName)) { // 如果指定sheet名,则取指定sheet中的内容. sheet = workbook.getSheet(sheetName); } else { // 如果传入的sheet名不存在则默认指向第1个sheet. sheet = workbook.getSheetAt(0); } if (sheet == null) { throw new IOException("文件sheet不存在"); } //获取数据 int rows = sheet.getLastRowNum(); if (rows == 0) { U.assertException("当前工作簿没数据"); } //行号从0开始,所以需要+1 rows = rows + 1; // 默认序号 int serialNum = 0; // 有数据时才处理 得到类的所有field. Field[] allFields = clazz.getDeclaredFields(); //用于校验是否存在某些字段 Map fieldNameMap = new HashMap(); // 定义一个map用于存放列的序号和field. Map fieldsMap = new HashMap(); for (Field field : allFields) { // 设置类的私有字段属性可访问. field.setAccessible(true); fieldsMap.put(++serialNum, field); fieldNameMap.put(field.getName(), field); } // DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DateFormatType.YYYY_MM_DD_HH_MM_SS.getValue()); DateTimeFormatter df = DateTimeFormatter.ofPattern(DateFormatType.YYYY_MM_DD.getValue()); SimpleDateFormat sdf = new SimpleDateFormat(DateFormatType.YYYY_MM_DD_HH_MM_SS.getValue()); // Row row = null; Cell cell = null; try { // 从第2行开始取数据,默认第一行是表头. for (int i = 1; i < rows; i++) { row = sheet.getRow(i); if (row == null) { continue; } T entity = clazz.newInstance(); for (int j = 0; j < serialNum; j++) { cell = row.getCell(j); if (cell == null) { continue; } // 从map中得到对应列的field. Field field = fieldsMap.get(j + 1); // 取得类型,并根据对象类型设置值. Class fieldType = field.getType(); String c; //excel数字精度问题:如果是数字类型,转化 if (cell.getCellTypeEnum().equals(CellType.NUMERIC) && fieldType != Date.class) { NumberFormat numberFormat = NumberFormat.getNumberInstance(); double d = cell.getNumericCellValue(); // 关键在这里! c = numberFormat.format(d); } else { // 先设置Cell的类型,然后就可以把纯数字作为String类型读进来了(这里数字类型 c可能存在精度问题) cell.setCellType(CellType.STRING); c = cell.getStringCellValue(); } if (StringUtils.isEmpty(c)) { continue; } if (String.class == fieldType) { field.set(entity, c); } else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) { field.set(entity, Integer.parseInt(c)); } else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) { field.set(entity, Long.valueOf(c)); } else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) { field.set(entity, Float.valueOf(c)); } else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) { field.set(entity, Short.valueOf(c)); } else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) { field.set(entity, Double.valueOf(c)); } else if (Character.TYPE == fieldType) { if (c.length() > 0) { field.set(entity, c.charAt(0)); } } else if (Date.class == fieldType) { if (cell.getCellTypeEnum() == CellType.NUMERIC) { cell.setCellValue(sdf.format(cell.getNumericCellValue())); c = sdf.format(cell.getNumericCellValue()); } else { c = cell.getStringCellValue(); } } else if (BigDecimal.class == fieldType) { try { field.set(entity, NumberUtil.toBigDecimal(c)); } catch (Exception ex) { U.assertException("数值类型转换失败,请检查单元格值是否符合规范"); } } else if (LocalDateTime.class == fieldType) { field.set(entity, LocalDateTime.parse(excelDoubleToDate(c, DateFormatType.YYYY_MM_DD_HH_MM_SS), dtf)); } else if (LocalDate.class == fieldType) { field.set(entity, LocalDate.parse(excelDoubleToDate(c, DateFormatType.YYYY_MM_DD), df)); } } if (BeanUtil.isNotEmpty(entity)) { //判断是否有行号字段,有的话赋值 if (fieldNameMap.containsKey("rowNum")) { //记录一下行数 fieldNameMap.get("rowNum").set(entity, row.getRowNum() + 1); } list.add(entity); } } } catch (Exception ex) { ex.printStackTrace(); U.assertException(StrUtil.format("解析第{}行,第{}列时出错,错误原因:{}", row == null ? "null" : row.getRowNum() + 1, cell == null ? "null" : cell.getColumnIndex() + 1, ex.getMessage())); } return list; } //解析Excel日期格式 public static String excelDoubleToDate(String strDate, DateFormatType dateFormatType) { try { SimpleDateFormat sdf = new SimpleDateFormat(dateFormatType.getValue()); Date tDate = doubleToDate(Double.parseDouble(strDate)); return sdf.format(tDate); } catch (Exception e) { //e.printStackTrace(); return strDate; } } //解析Excel日期格式 public static Date doubleToDate(Double dVal) { Date tDate = new Date(); long localOffset = tDate.getTimezoneOffset() * 60000; //系统时区偏移 1900/1/1 到 1970/1/1 的 25569 天 tDate.setTime((long) ((dVal - 25569) * 24 * 3600 * 1000 + localOffset)); return tDate; } /** * 常规字体-微软雅黑-12号 */ public static HSSFFont getFont(HSSFWorkbook wb) { HSSFFont font = wb.createFont(); font.setFontHeightInPoints((short) 12);//设置字体大小 font.setFontName("微软雅黑"); return font; } /** * 白色字体-微软雅黑-12号 */ public static HSSFFont getWhiteFont(HSSFWorkbook wb) { HSSFFont font = wb.createFont(); font.setFontHeightInPoints((short) 12);//设置字体大小 font.setFontName("微软雅黑"); font.setColor(HSSFColor.HSSFColorPredefined.WHITE.getIndex()); font.setBold(true); return font; } /** * 标题字体-微软雅黑-12号-加粗 */ public static HSSFFont getTitleFont(HSSFWorkbook wb) { HSSFFont font = getFont(wb); font.setBold(true); return font; } /** * 常规字体-微软雅黑-12号-红色 */ public static HSSFFont getRedFont(HSSFWorkbook wb) { HSSFFont font = getFont(wb); font.setColor(Font.COLOR_RED); return font; } /** * 单元格样式-自动换行-全边框-左右垂直居中 */ public static CellStyle getCellStyle(HSSFWorkbook wb, HSSFFont font) { CellStyle style = wb.createCellStyle();//新建样式对象 style.setWrapText(true);//设置自动换行 style.setAlignment(HorizontalAlignment.CENTER);//居中 style.setVerticalAlignment(VerticalAlignment.CENTER);//居中 style.setBorderBottom(BorderStyle.THIN);//下边框 style.setBorderLeft(BorderStyle.THIN);//左边框 style.setBorderRight(BorderStyle.THIN);//右边框 style.setBorderTop(BorderStyle.THIN);//上边框 style.setFont(font); return style; } /** * 单元格样式-自动换行-全边框-左右垂直居中-背景颜色 */ public static CellStyle getCellStyle(HSSFWorkbook wb, HSSFFont font, short bg) { CellStyle style = getCellStyle(wb, font); //设置背景色 style.setFillForegroundColor(bg); //设置填充样式 style.setFillPattern(FillPatternType.SOLID_FOREGROUND); return style; } /** * 设置下拉框(注意单元格内的字符不能超过255) * * @param sheet 指定sheet页 * @param values 下拉框的值 * @param firstRow 起始行号 * @param lastRow 起始行号 * @param firstCol 起始列号 * @param lastCol 终止列号 */ public static void setDropDownBox(HSSFSheet sheet, String[] values, Integer firstRow, Integer lastRow, Integer firstCol, Integer lastCol) { // 加载下拉列表内容 DVConstraint constraint = DVConstraint.createExplicitListConstraint(values); // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 CellRangeAddressList regions = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol); // 数据有效性对象 HSSFDataValidation data_validation_list = new HSSFDataValidation(regions, constraint); sheet.addValidationData(data_validation_list); } /** * sheet合并, 合并后删除数据源sheet * * @param workbook * @param sourceSheet 数据源 * @param targetSheet 合并到 * @return * @throws IOException */ public static void mergeSheet(XSSFWorkbook workbook, int sourceSheet, int targetSheet) throws IOException { final XSSFSheet target = workbook.getSheetAt(targetSheet); final XSSFSheet source = workbook.getSheetAt(sourceSheet); int lastRowNum = target.getLastRowNum(); final List mergedRegions = source.getMergedRegions(); //处理合并后的mergedRegion for (CellRangeAddress mergedRegion : mergedRegions) { mergedRegion.setFirstRow(mergedRegion.getFirstRow() + lastRowNum + 1); mergedRegion.setLastRow(mergedRegion.getLastRow() + lastRowNum + 1); } //逐行复制 for (int i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3