Отправить электронное письмо с HTML-шаблоном
Отправить электронное письмо с HTML-шаблоном

Обзор

Чтобы улучшить стиль отображения содержимого электронной почты, обычные текстовые электронные письма можно преобразовать в формат содержимого HTML. на Яве,Этого можно достичь с помощью технологии шаблонов страниц. Конкретно,Можно использоватьThymeleafшаблон。

Конкретная реализация

первый,在项目середина引入Thymeleafполагаться:

Язык кода:javascript
копировать
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.15.RELEASE</version>
</dependency>

Во-вторых, напишите содержимое шаблона страницы:

Язык кода:javascript
копировать
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>TOP100Двухнедельный дополнительный мониторинг лучших публикаций об автомобильных сериях и автомобильных друзьях.</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <style type="text/css">
        .znwh_tb {
            border: 1px solid rgba(87, 84, 84, 0.99);
            border-collapse:collapse;
        }
        .znwh_tb th,
        .znwh_tb td {
            border: 1px solid #545454;
            padding: 3px 5px;
        }
        .znwh_tb th {
            background-color:#DCDCDC;
        }
    </style>
</head>
<body style="margin: 0; padding: 0;">
<h3>Статистика постов Essence</h3>
<p>время:<span th:text="${startDate}"></span>-<span th:text="${endDate}"></span>,Количество новых сообщений:<span th:text="${bbsIncrement}"></span></p>

<h3>Сортировка по номеру чтения в порядке убыванияTOP<span th:text="${topSize}"></span>Список избранных сообщений</h3>
       <table class="znwh_tb">
    <tr>
        <th>серийный номер</th><th>发帖время</th><th>Добавить дату</th><th>Количество чтений</th><th>Количество комментариев</th><th>Количество лайков</th><th>Количество акций</th><th>серия автомобилей</th><th>заголовок</th>
    </tr>
    <tr th:each="bbs,bbsStat:${bbsList}">
        <td th:text="${bbsStat.index+1}"></td>
        <td th:text="${#dates.format(bbs.publishTimeDate, 'yyyy-MM-dd HH:mm:ss')}"></td>
        <td th:text="${#dates.format(bbs.createdStimeDate, 'yyyy-MM-dd HH:mm:ss')}"></td>
        <td th:text="${bbs.viewCount}"></td>
        <td th:text="${bbs.commentCount}"></td>
        <td th:text="${bbs.likeCount}"></td>
        <td th:text="${bbs.shareCount}"></td>
        <td th:text="${bbs.seriesName}"></td>
        <td><a th:href="@{${bbs.originUrl}}" rel="noopener noreferrer"><span th:text="${bbs.title}"></span></a></td>
    </tr>
</table>
<p><b>Примечание:</b>Полные данные смотрите в прикреплённом документе.。</p>
</body>
</html>

Наконец, шаблон страницы загружается для визуализации окончательного результата.

Язык кода:javascript
копировать
private static void buildTop100SeriesBbsMail(List<CyqBbs> bbsList) throws IOException {
	//Создаем шаблонизатор
	ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
	resolver.setPrefix("templates/");//Каталог, в котором находится шаблон, относительно пути к классам текущего загрузчика классов.
	resolver.setSuffix(".html");//Суффикс файла шаблона
	TemplateEngine templateEngine = new TemplateEngine();
	templateEngine.setTemplateResolver(resolver);

	//Создаем контекст (модель)
	Context context = new Context();
	context.setVariable("startDate", "10.21");
	context.setVariable("endDate", "11.10");
	context.setVariable("bbsIncrement", "100");
	context.setVariable("topSize", "50");
	context.setVariable("bbsList", bbsList);

	//рендеринг шаблона
	String fileName = "dcd_result.html";
	FileWriter write = new FileWriter(fileName);
	templateEngine.process("dcd_top100series_bbs_monitor_mail", context, write);
	write.close();
}

public static void main(String[] args) throws IOException {
	CyqBbs bbs = CyqBbs.builder()
				.id(10)
				.publishTimeDate(Calendar.getInstance().getTime())
				.createdStime(LocalDateTime.now())
				.behotTime(System.currentTimeMillis())
				.seriesName("Эвита 11")
				.viewCount(100)
				.commentCount(1000)
				.likeCount(10)
				.shareCount(2)
				.originUrl("http://www.baidu.com")
				.title("Тестовые данные")
				.build();
	ZoneId zoneId = ZoneId.systemDefault();
	ZonedDateTime zdt = bbs.getCreatedStime().atZone(zoneId);
	Date createdTimeDate = Date.from(zdt.toInstant());
	bbs.setCreatedStimeDate(createdTimeDate);
	List<CyqBbs> bbsList = Collections.singletonList(bbs);
	buildTop100SeriesBbsMail(bbsList);
}

Окончательный результат выглядит следующим образом:

Язык кода:javascript
копировать
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>TOP100Двухнедельный дополнительный мониторинг лучших публикаций об автомобильных сериях и автомобильных друзьях.</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <style type="text/css">
            .znwh_tb { 
                border: 1px solid rgba(87, 84, 84, 0.99); 
                border-collapse:collapse; 
            } 
            .znwh_tb th,
            .znwh_tb td {
                border: 1px solid #545454; 
                padding: 3px 5px; 
            }
            .znwh_tb th {
                background-color:#DCDCDC;
            }
        </style>
    </head>
    <body style="margin: 0; padding: 0;">
        <h3>Статистика постов Essence</h3>
        <p>время:<span>10.21</span>-<span>11.10</span>,Количество новых сообщений:<span>100</span></p>
        
        <h3>Сортировка по номеру чтения в порядке убыванияTOP<span>50</span>Список избранных сообщений</h3>
       <table class="znwh_tb">
            <tr>
                <th>серийный номер</th><th>发帖время</th><th>Добавить дату</th><th>Количество чтений</th><th>Количество комментариев</th><th>Количество лайков</th><th>Количество акций</th><th>серия автомобилей</th><th>заголовок</th>
            </tr>
            <tr>
                <td>1</td>
                <td>2022-12-21 18:34:25</td>
                <td>2022-12-21 18:34:26</td>
                <td>100</td>
                <td>1000</td>
                <td>10</td>
                <td>2</td>
                <td>Эвита11</td>
                <td><a href="http://www.baidu.com" rel="noopener noreferrer"><span>данные испытаний</span></a></td>
            </tr>
        </table>
        <p><b>Примечание:</b>Полные данные смотрите в прикреплённом документе.。</p>
    </body>
</html>

Хочу это здесьУведомление: Различные почтовые клиенты имеют разные эффекты совместимости со стилями CSS, поэтому лучше всего полностью протестировать результаты отображения распространенных почтовых клиентов.

По сравнению с электронными письмами в формате HTML, реализованными с использованием технологии шаблонов страниц, прямой вывод HTML-контента вручную очень неуклюж и сложен в обслуживании. Ниже приводится ссылка на то, как вручную вывести строку HTML:

Язык кода:javascript
копировать
private static String buildTop100SeriesBbsHtmlStr(List<CyqBbs> bbsList) {
	StringBuilder builder = new StringBuilder();
	builder.append("<html>");
	builder.append("<head>");
	builder.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />");
	builder.append("<title>TOP100Двухнедельный дополнительный мониторинг лучших публикаций об автомобильных сериях и автомобильных друзьях.</title>");
	builder.append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>");
	builder.append("<style type=\"text/css\">");
	builder.append(".znwh_tb { border: 1px solid rgba(87, 84, 84, 0.99);border-collapse:collapse; }");
	builder.append(".znwh_tb th,.znwh_tb td {border: 1px solid #545454; padding: 3px 5px; }");
	builder.append(".znwh_tb th { background-color:#DCDCDC; }");
	builder.append("</style>");
	builder.append("</head>");
	builder.append("<body style=\"margin: 0; padding: 0;\">");
	builder.append("<h3>Статистика постов Essence</h3>");
	builder.append("<p>время:").append("10.21").append("-").append("11.10").append(",Количество новых сообщений:").append(100).append("</p>");
	builder.append("<h3>Сортировка по номеру чтения в порядке убыванияTOP").append(50).append("Список избранных сообщений</h3>");
	builder.append("<table class=\"znwh_tb\">");
	builder.append("<tr><th>серийный номер</th><th>发帖время</th><th>Добавить дату</th><th>Количество чтений</th><th>Количество комментариев</th><th>Количество лайков</th><th>Количество акций</th><th>серия автомобилей</th><th>заголовок</th></tr>");
	for (int i = 0; i < bbsList.size(); i++) {
	CyqBbs bbs = bbsList.get(i);
	builder.append("<tr>");
	builder.append("<td>").append(i).append("</td>");
	builder.append("<td>").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(bbs.getPublishTimeDate())).append("</td>");
	builder.append("<td>").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(bbs.getBehotTime()))).append("</td>");
	builder.append("<td>").append(bbs.getViewCount()).append("</td>");
	builder.append("<td>").append(bbs.getCommentCount()).append("</td>");
	builder.append("<td>").append(bbs.getLikeCount()).append("</td>");
	builder.append("<td>").append(bbs.getShareCount()).append("</td>");
	builder.append("<td>").append(bbs.getSeriesName()).append("</td>");
	builder.append("<td>").append("<a href=\"").append(bbs.getOriginUrl()).append("\" rel=\"noopener noreferrer\">").append(bbs.getTitle()).append("</a>").append("</td>");
	builder.append("</tr>");
	}
	builder.append("</table>");
	builder.append("<p><b>Примечание:</b>Полные данные смотрите в прикреплённом документе.。</p>");
	builder.append("</body>");
	builder.append("</html>");
	return builder.toString();
}

Общие классы сущностей, которые они используют, определяются следующим образом:

Язык кода:javascript
копировать
@Data
@Builder
static class CyqBbs {
	private Integer id;
	private String title;
	private String content;
	private String originUrl;
	private String authorName;
	private String cover;
	private String keywords;
	private String tags;
	private String seriesId;
	private String seriesName;
	private Integer commentCount;
	private Integer likeCount;
	private Integer viewCount;
	private Integer playCount;
	private Integer shareCount;
	private Integer duration;
	private Long publishTime;
	private Date publishTimeDate;
	private Long behotTime;
	private LocalDateTime createdStime;
	private Date createdStimeDate;
	private LocalDateTime modifiedStime;
}
boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose