由于在公司工作,常年出差,每天都要以日报的形式向公司汇报当天的工作内容。而日报的内容大体上就只有当天工作的主要内容时变化的,其余的都是不变 的。 而我的电脑刚打开excel有点卡,因此决定使用JavaMail结合poi写一个简单excel模板替换并使用JavaMail发送邮件的小程序。

主要思路如下:

1.加载配置文件(使用yaml作为配置文件)

配置文件中存放的是发送邮件需要用的一些配置信息和excel模板中需要替换的数据

比喻:邮件使用的协议、发送人、收件人、等等信息

2.加载excel模板,读取模板,使用上一步中配置信息替换掉模板中的数据,然后生成excel文件

3.使用JavaMail发送邮件

要注意乱码的处理。

4.将代码打包成一个可执行的Jar包(最终只需要修改一下配置文件即可使用)

5.项目的源代码,用附件上传失败了。   链接:http://pan.baidu.com/s/1dDCU593 密码:6xpi

项目采用maven构建,但是为了修改配置文件方便,并没有使用maven的规范,将配置文件放到src/main/resources目录中。

代码如下:

  1. /**
  2. * 读取yaml配置文件,读取excel模板并生成excel文件,在使用JavaMail发送。
  3. *
  4. * @author huan
  5. *
  6. */
  7. public class App {
  8. // 配置文件的名称
  9. private static final String CONFIGER_YAML_FILE_NAME = "sendMailConfig.yaml";
  10. // 日报的excel模板
  11. private static final String EXCEL_TEMPLETE = "ExcelTemplete.xls";
  12. public static void main(String[] args) {
  13. // 1.加载属性文件
  14. Map<String, String> propMap = null;
  15. try {
  16. propMap = loadConfigYamlFile();
  17. } catch (FileNotFoundException e1) {
  18. e1.printStackTrace();
  19. System.out.println("加载yaml文件失败");
  20. System.exit(1);
  21. }
  22. // 将当前日期放到map中
  23. propMap.put("${currDate}", new SimpleDateFormat("yyyyMMdd").format(new Date()));
  24. System.out.println("输出配置文件信息开始...");
  25. for (Map.Entry<String, String> entry : propMap.entrySet()) {
  26. System.out.println(entry.getKey() + " --> " + entry.getValue());
  27. }
  28. System.out.println("输出配置文件信息结束...");
  29. // 2.加载excel模板
  30. Workbook workbook = loadExcelTemplete();
  31. if (workbook == null) {
  32. return;
  33. }
  34. // 3.获取第一个sheet页
  35. Sheet sheet = workbook.getSheetAt(0);
  36. if (null == sheet) {
  37. System.out.println("获取第一个sheet页失败");
  38. return;
  39. }
  40. String dayReportName = "Test-日报-" + propMap.get("${reportPer}") + "-" + propMap.get("${currDate}") + ".xls";
  41. System.out.println("生成新的日报的名称:" + dayReportName);
  42. // 替换模板中的内容
  43. for (Row row : sheet) {
  44. for (Cell cell : row) {
  45. int cellType = cell.getCellType();
  46. // 根据单元格的中内容的类型,得到单元格中的值
  47. String cellContent = getCellContentByCellType(cell, cellType);
  48. if (propMap.containsKey(cellContent)) {
  49. setCellValue(propMap, cell, cellContent);
  50. }
  51. }
  52. }
  53. // 将替换后的数据excel保存到本地
  54. BufferedOutputStream bos = null;
  55. try {
  56. bos = new BufferedOutputStream(new FileOutputStream(dayReportName));
  57. workbook.write(bos);
  58. workbook.close();
  59. bos.close();
  60. } catch (IOException e1) {
  61. e1.printStackTrace();
  62. }
  63. System.out.println(dayReportName + " --> 生成成功!!!");
  64. // 发送邮件开始
  65. try {
  66. sendMail(propMap, dayReportName);
  67. } catch (Exception e) {
  68. e.printStackTrace();
  69. System.out.println("邮件发送失败");
  70. System.exit(1);
  71. }
  72. System.out.println("邮件发送成功");
  73. // 归档文件
  74. archiveFile(dayReportName);
  75. }
  76. // 归档日报
  77. private static void archiveFile(String dayReportName) {
  78. // 1.判断目录是否存在
  79. Calendar calendar = Calendar.getInstance();
  80. int _month = calendar.get(Calendar.MONTH) + 1;
  81. String month = _month + "";
  82. if (_month < 10) {
  83. month = "0" + _month;
  84. }
  85. String dir = "日报归档" + File.separator + month;
  86. File dirFile = new File(dir);
  87. if (!dirFile.exists()) {
  88. dirFile.mkdirs();
  89. System.out.println("创建目录:" + dirFile.getAbsolutePath());
  90. }
  91. File dayReportFile = new File(dayReportName);
  92. File f = new File(dir, dayReportName);
  93. dayReportFile.renameTo(f);
  94. System.out.println("文件归档成功:" + f.getAbsolutePath());
  95. }
  96. /**
  97. * 发送日报
  98. *
  99. * @param propMap
  100. * @param dayReportName
  101. * @throws MessagingException
  102. * @throws IOException
  103. */
  104. private static void sendMail(final Map<String, String> propMap, String dayReportName) throws MessagingException, IOException {
  105. Properties props = new Properties();
  106. props.setProperty("mail.host", propMap.get("${mail.host}"));
  107. props.setProperty("mail.smtp.auth", propMap.get("${mail.smtp.auth}"));
  108. props.setProperty("mail.transport.protocol", propMap.get("${mail.transport.protocol}"));
  109. Authenticator auth = new Authenticator() {
  110. @Override
  111. protected PasswordAuthentication getPasswordAuthentication() {
  112. // 邮箱的用户名和密码
  113. return new PasswordAuthentication(propMap.get("${sendPer}"), propMap.get("${sendPerPwd}"));
  114. }
  115. };
  116. // 1.创建邮件的第一步: 创建session对象
  117. Session session = Session.getInstance(props, auth);
  118. // 设置调试模式 可以关闭
  119. session.setDebug(true);
  120. // 2.创建邮件的第二步:创建MimeMessage对象
  121. // 创建邮件对象
  122. MimeMessage msg = new MimeMessage(session);
  123. // 设置发送人
  124. msg.setFrom(new InternetAddress(propMap.get("${sendPer}")));
  125. // 设置收件人
  126. msg.addRecipients(RecipientType.TO, InternetAddress.parse(propMap.get("${receivePer}")));
  127. // 设置收件人 类型为 抄送
  128. msg.addRecipients(RecipientType.CC, InternetAddress.parse(propMap.get("${CC}")));
  129. // 设置邮件的主题
  130. msg.setSubject(dayReportName);
  131. MimeMultipart partList = new MimeMultipart();
  132. // 写签名
  133. MimeBodyPart part1 = new MimeBodyPart();
  134. System.out.println(propMap.get("${mailSign}"));
  135. part1.setContent(propMap.get("${mailSign}"), "text/html;charset=utf-8");
  136. // 写附件
  137. MimeBodyPart part2 = new MimeBodyPart();
  138. part2.attachFile(new File(dayReportName));
  139. part2.setFileName(MimeUtility.encodeText(dayReportName));
  140. // 把部件添加到集合中
  141. partList.addBodyPart(part1);
  142. partList.addBodyPart(part2);
  143. msg.setContent(partList);
  144. // 3. 创建邮件的第三步,发送 Transport
  145. Transport.send(msg);
  146. }
  147. /**
  148. * 设置单元格的样式
  149. *
  150. * @param propMap
  151. * @param cell
  152. * @param cellContent
  153. */
  154. private static void setCellValue(Map<String, String> propMap, Cell cell, String cellContent) {
  155. if (cellContent.equals("${currDate}")) {// 日期单独处理
  156. System.out.println("替换[" + cellContent + "]为[" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + "]");
  157. cell.setCellValue(new Date());
  158. } else {
  159. String cellValue = propMap.get(cellContent);
  160. System.out.println("替换[" + cellContent + "]为[" + cellValue + "]");
  161. cell.setCellValue(cellValue);
  162. }
  163. }
  164. /**
  165. * @param cell
  166. * @param cellType
  167. */
  168. private static String getCellContentByCellType(Cell cell, int cellType) {
  169. String cellContent = "";
  170. switch (cellType) {
  171. case Cell.CELL_TYPE_STRING:
  172. cellContent = cell.getStringCellValue();
  173. break;
  174. case Cell.CELL_TYPE_BLANK:
  175. cellContent = "";
  176. break;
  177. case Cell.CELL_TYPE_NUMERIC:
  178. cellContent = cell.getNumericCellValue() + "";
  179. break;
  180. case Cell.CELL_TYPE_BOOLEAN:
  181. cellContent = cell.getBooleanCellValue() + "";
  182. break;
  183. default:
  184. System.err.println("出现未知的单元格类型,系统退出。");
  185. System.exit(1);
  186. break;
  187. }
  188. return cellContent;
  189. }
  190. /**
  191. * 生成Excel的模板
  192. *
  193. * @throws IOException
  194. * @throws FileNotFoundException
  195. */
  196. private static Workbook loadExcelTemplete() {
  197. try {
  198. Workbook workbook = WorkbookFactory.create(new FileInputStream(new File(EXCEL_TEMPLETE)));
  199. return workbook;
  200. } catch (Exception e) {
  201. System.out.println("加载Excel模板出错...");
  202. e.printStackTrace();
  203. }
  204. return null;
  205. }
  206. // 加载配置文件文件
  207. @SuppressWarnings("unchecked")
  208. private static Map<String, String> loadConfigYamlFile() throws FileNotFoundException {
  209. Yaml yaml = new Yaml();
  210. Iterable<Object> iterable = yaml.loadAll(new FileInputStream(new File(CONFIGER_YAML_FILE_NAME)));
  211. Iterator<Object> it = iterable.iterator();
  212. Map<String, String> configerMap = new HashMap<String, String>();
  213. while (it.hasNext()) {
  214. Map<String, String> map = (Map<String, String>) it.next();
  215. for (Map.Entry<String, String> entry : map.entrySet()) {
  216. configerMap.put("${" + entry.getKey().trim() + "}", entry.getValue().trim());
  217. }
  218. }
  219. return configerMap;
  220. }
  221. }
项目截图如下:  最终打包成的目录如下:
点击run.bat执行后,就可以看到

替换excel模板中的内容并使用JavaMail发送邮件的更多相关文章

  1. JAVA POI替换EXCEL模板中自定义标签(XLSX版本)满足替换多个SHEET中自定义标签

    个人说明:为了简单实现导出数据较少的EXCEL(根据自定义书签模板) 一.替换Excel表格标签方法```/** * 替换Excel模板文件内容 * @param map * 需要替换的标签建筑队形式 ...

  2. java代码将excel文件中的内容列表转换成JS文件输出

    思路分析 我们想要把excel文件中的内容转为其他形式的文件输出,肯定需要分两步走: 1.把excel文件中的内容读出来: 2.将内容写到新的文件中. 举例 一张excel表中有一个表格: 我们需要将 ...

  3. 根据excel表格中的内容更新Sql数据库

    关于[无法创建链接服务器 "(null)" 的 OLE DB 访问接口 SQL Server 2008读取EXCEL数据时,可能会报这个错误:无法创建链接服务器 "(nu ...

  4. C# 导出数据到Excel模板中(转)

    今天做报表的时候遇到了多表头的问题,而且相应的报表的格式都一样.所以就采用了报表模板的方式来进行. 第一步:在开发的当前项目中引入:Microsoft.Office.Interop.Excel:Sys ...

  5. 从Excel文件中读取内容

    从Excel文件中读取内容 global::System.Web.HttpPostedFileBase file = Request.Files["txtFile"]; strin ...

  6. 根据Excel文件中的内容,修改指定文件夹下的文件名称

    问题:根据Excel文件中内容,把文件名称由第2列,改为第1列.比如:把文件“123.jpg”修改为“1.jpg”.

  7. 用配置文件里面的参数值替换yaml模板中的变量值【python】

    用配置文件里面的参数值替换yaml模板中的变量值[python] #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2019/9/20 1 ...

  8. poi读取excel模板,填充内容并导出,支持导出2007支持公式自动计算

    /** * 版权所有(C) 2016 * @author www.xiongge.club * @date 2016-12-7 上午10:03:29 */ package xlsx; /** * @C ...

  9. POI根据EXCEL模板,修改内容导出新EXCEL (只支持HSSF)

    package excelPoiTest; import java.io.File; import java.io.FileInputStream; import java.io.FileOutput ...

随机推荐

  1. openswan协商流程之(二):main_inI1_outR1()

    主模式第二包:main_inI1_outR1() 文章目录 主模式第二包:main_inI1_outR1() 1. 序言 2. `main_inI1_outR1()`处理流程图 3. `main_in ...

  2. JS015. 数据存储方式与位置(堆内存、栈内存、指针)

    数据 - 基本类型 Undefined  ,  Null  ,  String  ,  Number  ,  Boolean  ,  Symbol (ES 6)  , 基本数据类型存储在栈内存中. 数 ...

  3. k8s资源管理(基础操作)

    1. 基础 本文实操基于k8s 1.22.1 # 可以查看资源分配情况 kubectl describe node # 全局资源情况查看 kubectl api-resources 1.1 apply ...

  4. sync 修饰符在Vue中如何使用

    在有些情况下,我们可能需要对一个 prop 进行"双向绑定".不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,且在父组件和子组件都没有明显的改动来源.   这 ...

  5. mysql忘记root密码连接本地库

    http://www.cnblogs.com/zf2011/archive/2012/03/13/2393387.html 今天想做个小项目,决定用mysql数据库,但是好久没用mysql了,也忘掉了 ...

  6. 机器学习——K-Means算法

    1 基础知识 相似度或距离 假设有 $m$ 个样本,每个样本由 $n$ 个属性的特征向量组成,样本合集 可以用矩阵 $X$ 表示 $X=[x_{ij}]_{mn}=\begin{bmatrix}x_{ ...

  7. centos7 未启用swap导致内存使用率过高。

    情况描述: 朋友在阿里云上有一台系统为CentOS7的VPS,内存为2GB,用于平时开发自己的项目时测试使用: 他在上面运行了5个docker实例,运行java程序:还有一个mysql服务: 上述5个 ...

  8. Orchard Core Framework Samples

    解决方案包含内容 多租户应用 一个ASP.NET Core MVC应用程序,它引用模块项目,并为两个启用了不同模块的租户提供支持. 此Web应用程序的主页提供了更多信息,并链接到两个租户和模块端点.租 ...

  9. Redis之品鉴之旅(五)

    Redis事务 原子性:就是最小的单位 一致性:好多命令,要么全部执行成功,要么全部执行失败 隔离性:一个会话和另一个会话之间是互相隔离的 持久性:执行了就执行了,数据保存在硬盘上 典型例子:银行转账 ...

  10. Azure Bicep(二)语法简介

    一,引言 上一篇文章有介绍到 Azure Bicep 的部署问题,文中也只是演示部署范围为 Sub,并将演示的 Azure Resource Group 到 Azure.给定 Bicep 文件,可以部 ...