网站砍价活动怎么做/互联网全媒体广告代理
1、项目介绍
1)项目功能
用户管理:分为管理员、和普通用户,设置不同用户的权限
电话本信息管理:支持管理员和普通用户对电话本的信息进行增删改操作,模糊查询(根据姓名、地址、单位)
文件批量导入:支持管理员通过excel文件批量导入电话本信息
分页功能:对电话本信息管理页面支持分页查看
电话本分组管理:对电话本进行分组,修改、移动、删除
邮件发送名片功能:支持管理员根据电话本信息向用户发送邮件,邮件内容为个人信息名片和附件
用户信息导出功能:导出个人用户的用户信息word文档
2)技术栈描述
前端 html+thymeleaf+jquery+css
后端 Spring Boot + Spring MVC + MyBatis Plus
数据库 MySQL
其他技术 POI Excel 、word文件导入导出、JavaMail API邮件发送
2、邮件发送具体实现
1)导入发送邮件需要的依赖
<!-- 邮件发送--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
2)添加邮件配置的参数(在application.yml配置文件中)
mail:host: smtp.qq.com #qq邮件服务器地址 有其他地址username: xxxxxxx@qq.com #发件人邮箱password: rwcafxsrjxfndfee #授权码default-encoding: UTF-8 #邮件登录字符集编码port: 25 #发件人邮件服务器端口
授权码的获取:首先登录QQ邮箱>>>登录成功后找到设置>>>然后找到邮箱设置>>>点击账户>>>找到POP3|SMTP服务>>>点击开启(开启需要验证,验证成功后会有一串授权码用于发送邮件使用)>>>验证成功
3)创建邮件发送controller
以发送个人信息为例
@AutowiredMailUtil mailUtil;/*** 邮件发送名片功能* @param contactId* @param userId* @return*/@RequestMapping("/sendEmailCard")public void sendEmailCard(Integer contactId, Integer userId){Contacts contacts = this.contactsService.getById(contactId);Users user = this.usersService.getById(contacts.getUserId());Integer gender0 = contacts.getGender();String gender = "男";if(gender0==1){gender="女";}String email = contacts.getEmail();String content="<html><body><h1>个人名片</h1><p>姓名:" +user.getUsername()+"</p><p>单位:" +contacts.getCompany()+"</p><p>性别:" +gender+"</p><p>年龄:" +contacts.getAge()+"</p><p>办公电话:" +contacts.getOfficePhone()+"</p><p>传真:" +contacts.getFax()+"</p><p>手机号码:" +contacts.getMobile()+"</p><p>电子邮件:" +contacts.getEmail()+"</p><p>地址:" +contacts.getAddress()+"</p><p>备注:" +contacts.getRemarks()+"</p></body></html>";String imgPath = "D:\\email\\个人信息表.docx";mailUtil.sendAttachmentsMail(email, "主题:电话信息验证", content, imgPath);}
4) 引入邮件发送工具包
package com.qcby.onlinephonebook.util;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;/*** <p><p/>** @Author: porridge* @Date:2022/3/30 10:17*/
@Component
public class MailUtil {@Value("${spring.mail.username}")String from;@AutowiredJavaMailSender mailSender;//简单邮件public void sendSimpleMail(String to, String subject, String content){SimpleMailMessage message = new SimpleMailMessage();message.setFrom(from); //发件人message.setTo(to);//收件人message.setSubject(subject); //标题message.setText(content); //文件内容try {mailSender.send(message);System.out.println("简单邮件发送成功!");} catch (Exception e){System.out.println("发送简单邮件时发生异常!"+e);}}//html格式邮件public void sendHtmlMail(String to, String subject, String content){MimeMessage message = mailSender.createMimeMessage();try {//true表示需要创建一个multipart messageMimeMessageHelper helper = new MimeMessageHelper(message, true);helper.setFrom(from);helper.setTo(to);helper.setSubject(subject);helper.setText(content, true);mailSender.send(message);System.out.println("html邮件发送成功!");} catch (MessagingException e) {System.out.println("发送html邮件时发生异常!"+e);}}//带附件的邮件public void sendAttachmentsMail(String to, String subject, String content, String filePath){MimeMessage message = mailSender.createMimeMessage();try {MimeMessageHelper helper = new MimeMessageHelper(message, true);helper.setFrom(from);helper.setTo(to);helper.setSubject(subject);helper.setText(content, true);FileSystemResource file = new FileSystemResource(new File(filePath));String fileName = filePath.substring(filePath.lastIndexOf(File.separator));helper.addAttachment(fileName, file);mailSender.send(message);System.out.println("带附件的邮件已经发送。");} catch (MessagingException e) {System.out.println("发送带附件的邮件时发生异常!" + e);}}//带静态资源的邮件public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId){MimeMessage message = mailSender.createMimeMessage();try {MimeMessageHelper helper = new MimeMessageHelper(message, true);helper.setFrom(from);helper.setTo(to);helper.setSubject(subject);helper.setText(content, true);FileSystemResource res = new FileSystemResource(new File(rscPath));helper.addInline(rscId, res);mailSender.send(message);System.out.println("嵌入静态资源的邮件已经发送。");} catch (MessagingException e) {System.out.println("发送嵌入静态资源的邮件时发生异常!" + e);}}
}
发送成功样例
3、word导出具体实现
1)实现思路
①组装数据
②获取根目录,创建模板文件
③将模板文件写入到根目录
④编译模板,渲染数据
⑤写入到指定目录位置,临时文件
⑥提供前端下载
⑦删除临时文件
2)导入word导出需要的依赖
<!-- word导出--><dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.10.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency>
3)在项目resource目录下创建word模板
word模板如下:
根据需要,{{}}里面写入需要写入的参数名
4)创建word导出的controller
/*** 个人信息word导出* @param response*/@RequestMapping("/exportWord")public void exportWord(Integer contactId, Integer userId, HttpServletResponse response) {Contacts contacts = this.contactsService.getById(contactId);String gender = "男";if(contacts.getGender()==1){gender = "女";}//1.组装数据Map<String, Object> params = new HashMap<>();params.put("name",contacts.getName());params.put("company", contacts.getCompany());params.put("gender", gender);params.put("age", contacts.getAge());params.put("officePhone", contacts.getOfficePhone());params.put("fax", contacts.getFax());params.put("mobile", contacts.getMobile());params.put("email", contacts.getEmail());params.put("address", contacts.getAddress());params.put("remarks", contacts.getRemarks());//2.获取根目录,创建模板文件String path = copyTempFile("word/info.docx");String fileName = System.currentTimeMillis() + ".docx";String tmpPath = "D:\\email\\" + fileName;try {//3.将模板文件写入到根目录//4.编译模板,渲染数据XWPFTemplate template = XWPFTemplate.compile(path).render(params);//5.写入到指定目录位置FileOutputStream fos = new FileOutputStream(tmpPath);template.write(fos);fos.flush();fos.close();template.close();//6.提供前端下载down(response, tmpPath, fileName);} catch (Exception e) {e.printStackTrace();} finally {//7.删除临时文件File file = new File(tmpPath);file.delete();File copyFile = new File(path);copyFile.delete();}}/*** 用于将文件下载到客户端* @param response* @param filePath 文件路径* @param realFileName 文件名称*/private void down(HttpServletResponse response, String filePath, String realFileName) {String percentEncodedFileName = null;try {percentEncodedFileName = percentEncode(realFileName);} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}StringBuilder contentDispositionValue = new StringBuilder();contentDispositionValue.append("attachment; filename=").append(percentEncodedFileName).append(";").append("filename*=").append("utf-8''").append(percentEncodedFileName);response.addHeader("Access-Control-Allow-Origin", "*");response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");response.setHeader("Content-disposition", contentDispositionValue.toString());response.setHeader("download-filename", percentEncodedFileName);try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));// 输出流BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());) {byte[] buff = new byte[1024];int len = 0;while ((len = bis.read(buff)) > 0) {bos.write(buff, 0, len);}} catch (Exception e) {e.printStackTrace();}}/*** 百分号编码工具方法* @param s 需要百分号编码的字符串* @return 百分号编码后的字符串*/public static String percentEncode(String s) throws UnsupportedEncodingException {String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());return encode.replaceAll("\\+", "%20");}/*** 复制模板文件用于写入,得到临时路径* @param s 模板文件的路径* @return*/private String copyTempFile(String s) {InputStream inputStream = getClass().getClassLoader().getResourceAsStream(s);String tempFileName = System.getProperty("user.home") + "/" + "info.docx";File tempFile = new File(tempFileName);try {FileUtils.copyInputStreamToFile(inputStream, tempFile);} catch (IOException e) {throw new RuntimeException(e);}return tempFile.getPath();}
导出成功样例:
相关文章:

项目实战之网络电话本之发送邮件名片和导出word版个人信息
1、项目介绍 1)项目功能 用户管理:分为管理员、和普通用户,设置不同用户的权限 电话本信息管理:支持管理员和普通用户对电话本的信息进行增删改操作,模糊查询(根据姓名、地址、单位) 文件批…...

前端面试问题汇总 - HTTP篇
1. 登录拦截如何实现? 在前端,可以拦截所有需要登录的请求,如果用户未登录或者登录过期,则跳转到登录页面。 2. http 缓存有哪些? 强缓存: 强缓存是指在客户端请求资源时,先检查本地是否存在缓存…...

Java的IO流
Day35 Java的IO流 概念 Java的IO流是用来处理输入和输出操作的机制,用于在程序和外部数据源(如文件、网络连接、内存等)之间进行数据传输。Java的IO流主要分为字节流和字符流两种类型,每种类型又分为输入流和输出流。 理解&#…...

Node.js 中的 RSA 加密、解密、签名与验证详解
引言 在现代的网络通信中,数据安全显得尤为重要。RSA加密算法因其非对称的特性,广泛应用于数据的加密、解密、签名和验证等安全领域。本文将详细介绍RSA算法的基本原理,并结合Node.js环境,展示如何使用内置的crypto模块和第三方库…...

vue+element作用域插槽
作用域插槽的样式由父组件决定,内容却由子组件控制。 在el-table使用作用域插槽 <el-table><el-table-column slot-scope" { row, column, $index }"></el-table-column> </el-table>在el-tree使用作用域插槽 <el-tree>…...

MUSA模型
MUSA模型在软件可靠性工程中起到的作用是估计软件的故障/失效数量和故障率。具体来说,MUSA模型包括基本模型和对数模型。 MUSA基本模型假设故障发生的时间间隔服从参数为lambda的指数分布。在这个模型中,当故障被检测到时,发生故障的部分会被…...

avicat连接异常,错误编号2059-authentication plugin…
错误原因为密码方式不对,具体可自行百度 首先管理员执行cmd进入 mysql安装目录 bin下边 我的是C:\Program Files\MySQL\MySQL Server 8.2\bin> 执行 mysql -u -root -p 然后输入密码 123456 进入mysql数据库 use mysql 执行 ALTER USER rootlocalhost IDE…...

阿里云云效CI/CD配置
1.NODEJS项目流水线配置(vue举例) nodejs构建配置 官方教程 注意:下图的dist是vue项目打包目录名称,根据实际名称配置 # input your command here cnpm cache clean --force cnpm install cnpm run build 主机部署配置 rm -rf /home/vipcardmall/frontend/ mkdir -p /home/…...

个人开发者,Spring Boot 项目如何部署
今天给大家分享一下,作为个人开发者,Spring Boot 项目是如何部署的。 环境介绍 Linux docker docker-compose 目录结构 erwin-windrunner - backups - data - jars - build-docker-compose.sh - docker-compose.yml - Dockerfile文件 Dockerfile …...

【Spring进阶系列丨第九篇】基于XML的面向切面编程(AOP)详解
文章目录 一、基于XML的AOP1.1、打印日志案例1.1.1、beans.xml中添加aop的约束1.1.2、定义Bean 1.2、定义记录日志的类【切面】1.3、导入AOP的依赖1.4、主配置文件中配置AOP1.5、测试1.6、切入点表达式1.6.1、访问修饰符可以省略1.6.2、返回值可以使用通配符,表示任…...

学习记录:转发和重定向
转发(Forward)和重定向(Redirect)是两种不同的 Web 请求处理方式,它们在功能和行为上有着显著的区别。 区别 转发(Forward): 服务器内部跳转:转发是服务器内部的行为&…...

实现(图像、视频等)数据上云存储
实现(图像、视频等)数据上云存储 实现(图像、视频等)数据上云存储通常涉及以下几个步骤: 选择云存储服务商: 根据您的需求、预算、地域覆盖、数据安全性、服务稳定性等因素,选择一家合适的云存储…...

LeetCode 454.四数相加II
LeetCode 454.四数相加II 1、题目 题目链接:454. 四数相加 II - 力扣(LeetCode) 给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <…...

GoogleNet网络训练集和测试集搭建
测试集和训练集都是在之前搭建好的基础上进行修改的,重点记录与之前不同的代码。 还是使用的花分类的数据集进行训练和测试的。 一、训练集 1、搭建网络 设置参数:使用辅助分类器,采用权重初始化 net GoogleNet(num_classes5, aux_logi…...

将数字状态码在后台转换为中文状态
这是我们的实体类 可以看出我们的状态status是2如过返回到前端我们根本不知道2代表的是什么,所以我们需要再这里将数字转换成能看懂的中文状态,首先我们创建一个枚举类 先将我们状态码所对应的中文状态枚举出来,然后创建一个静态方法&#…...

2017NOIP普及组真题 4. 跳房子
线上OJ: 一本通:http://ybt.ssoier.cn:8088/problem_show.php?pid1417\ 核心思想 首先、本题中提到 “ 至少 要花多少金币改造机器人,能获得 至少 k分 ”。看到这样的话语,基本可以考虑要使用 二分答案。 那么,本题中…...

网络与 Internet因特网的基本概念
目录 网络Internet (互联网或互连网)Internet(因特网)待续、更新中 网络 指将分布在不同地理位置的、相同或不同类型的网络通过网络互连设备(中继器、网桥、路由器或网关等)相互连接,形成一个范…...

vue-router 中 router-link 与 a 标签的区别
文章目录 前言 a标签定义 router-link定义 总结 前言 vue-router 中 router-link 与 a 标签的区别 a标签定义 <a> 标签定义超链接,用于从一张页面链接到另一张页面。 从一张页面跳转到另一张页面,但从这里来说就违背了多视图的单页Web应用这个…...

MySQL基础知识——MySQL事务
事务背景 什么是事务? 一组由一个或多个数据库操作组成的操作组,能够原子的执行,且事务间相互独立; 简单来说,事务就是要保证一组数据库操作,要么全部成功,要么全部失败。 注:MyS…...

【架构方法论(一)】架构的定义与架构要解决的问题
文章目录 一. 架构定义与架构的作用1. 系统与子系统2. 模块与组件3. 框架与架构4. 重新定义架构:4R 架构 二、架构设计的真正目的-别掉入架构设计的误区1. 是为了解决软件复杂度2. 简单的复杂度分析案例 三. 案例思考 本文关键字 架构定义 架构与系统的关系从业务逻…...

基于springboot实现人口老龄化社区服务与管理系统项目【项目源码+论文说明】计算机毕业设计
基于springboot实现人口老龄化社区服务与管理系统演示 摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了人口老龄化社区服务与管理平台的开发全过程。通过分析人口老龄化社区服务与管理平台方面的不足ÿ…...

代码随想录算法训练营第三十七天| LeetCode 738.单调递增的数字、总结
一、LeetCode 738.单调递增的数字 题目链接/文章讲解/视频讲解:https://programmercarl.com/0738.%E5%8D%95%E8%B0%83%E9%80%92%E5%A2%9E%E7%9A%84%E6%95%B0%E5%AD%97.html 状态:已解决 1.思路 如何求得小于等于N的最大单调递增的整数?98&am…...

C++动态内存管理 解剖new/delete详细讲解(operator new,operator delete)
讨厌抄我作业和不让我抄作业的人 讨厌插队和不让我插队的人 讨厌用我东西和不让我用东西的人 讨厌借我钱和不借给我钱的人 讨厌开车加塞和不让我加塞的人 讨厌内卷和打扰我内卷的人 一、C中动态内存管理 1.new和delete操作内置类型 2.new和delete操作自定义类型 二、operat…...

python-re正则笔记0.2.0
1. 匹配linux文件路径 from re import match, search,findall str"sh refreshConfig.sh /opt/client/ccc.txt /opt/client/ccc.dfs 胜多负少的"patter1"\/.\.\w" print(findall(patter1, str))""" [/opt/client/ccc.txt /opt/client/ccc…...

.NET SignalR Redis实时Web应用
环境 Win10 VS2022 .NET8 Docker Redis 前言 什么是 SignalR? ASP.NET Core SignalR 是一个开放源代码库,可用于简化向应用添加实时 Web 功能。 实时 Web 功能使服务器端代码能够将内容推送到客户端。 适合 SignalR 的候选项: 需要从服…...

【热门话题】常见分类算法解析
🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 常见分类算法解析1. 逻辑回归(Logistic Regression)2. 朴…...

有效利用MRP能为中小企业带来什么?
在离散制造企业,主流的生产模式主要为面向订单生产和面向库存生产(又称为预测生产),在中小企业中,一般为面向订单生产,也有部分面向库存和面向订单混合的生产方式(以面向订单为主,面…...

InternlM2
第一次作业 基础作业 进阶作业 1. hugging face下载 2. 部署 首先,从github上git clone仓库 https://github.com/InternLM/InternLM-XComposer.git然后里面的指引安装环境...

2024-12.python高级语法
异常处理 首先我们要理解什么叫做**"异常”**? 在程序运行过程中,总会遇到各种各样的问题和错误。有些错误是我们编写代码时自己造成的: 比如语法错误、调用错误,甚至逻辑错误。 还有一些错误,则是不可预料的错误…...

【C语言】贪吃蛇项目(1) - 部分Win32 API详解 及 贪吃蛇项目思路
文章目录 一、贪吃蛇项目需要实现的基本功能二、Win32 API介绍2.1 控制台2.2 部分控制台命令及调用函数mode 和 title 命令COORD 命令GetStdHandle(获取数据)GetConsoleCursorInfo(获取光标数据)SetConsoleCursorInfo (…...