裁缝式开发:用MATLAB批量发送一封图文并茂的邮件

问题背景

前几天,女朋友公司要求她周末加班发送宣传推广邮件给高校老师,而我才知晓之前她们发送邮件全靠手动…目前待发名单至少有三千人,而现在才发了一百多封,我的心情如下
在这里插入图片描述
为了能够不加班周末去放风筝,于是我决定亲自动手。但是毕竟我不是搞Web开发的,应该从哪下手呢?答案是:面向百度编程。

实现过程

组装轮子——MATLAB如何发送一封图文并茂的邮件?

1.发送一封普通的邮件

MathWorks 在官方文档里提供了sendmail函数用于向指定的地址列表发送电子邮件

在这里插入图片描述

需要设置的参数如下:

发件人邮箱地址、发件人邮箱授权码(注意不是密码,而是邮箱用于登录第三方邮件客户端的专用密码)、SMTP服务器地址、收件人邮箱、主题、内容、附件

详细请见:https://ww2.mathworks.cn/help/matlab/ref/sendmail.html?searchHighlight=sendmail&s_tid=srchtitle_sendmail_1(MathWorks官方文档)
https://blog.csdn.net/eswai/article/details/53454987(使用例程)

2.发送html格式的邮件

mathworks官方给出的sendmail函数虽然能够实现自动发送邮件,但有个致命的缺点是,它只能支持普通文本,并不能发送html格式,因此排版、字号、颜色等参数统统都不能实现。距离我们的目标还有一段距离。
在这里插入图片描述
经过互联网的大海捞针,终于找到这样一篇帖子,有位老哥提出来可以修改sendmail的库函数实现发送html邮件。(https://undocumentedmatlab.com/articles/sending-html-emails-from-matlab)翻译过来主要有两点:
1.HTML 格式需要调用消息对象的 setContent() 方法,而不是 setText()

2. 我们需要指定为消息编码的一部分’text/html’

当然,为了避免重复造轮子,我们选择直接白嫖(狗头)
在这里插入图片描述

3.如何写html?

那么问题又来了,虽然我们知道可以通过html格式发送一封排版整齐,图文并茂的邮件,可是对于小白来说,要想通过html书写邮件并不是一件容易的事情。但是我们可以换个思路,将文本内容转换为html。
直接检索文本转html,会发现有许多在线工具,支持txt,docx等格式。
在这里插入图片描述
打开转换好的xxx.html文件后,按Ctrl+U进入网页后台,就可以看到文本对应的html代码了。

4.发送图片

那么问题又来了,假如我们的邮件中带有图片内容,又不想通过附件的方式发送,而是嵌入到邮件中,通过文本转换的方式能够生成图片的html代码吗?答案是可以的,但是生成的代码是图片的链接,在发送邮件之后,邮件系统往往会屏蔽掉图片链接,从而图片无法显示。针对此问题,一般可以通过“CID内嵌图像”方式完成。

CID 的工作原理是将图像附加到要发送的电子邮件中,然后使用引用该图像的标准 HTML图像标记,以便在用户打开该图像时最终将其嵌入到电子邮件中。

但是由于该方法同样涉及到需要改动sendmail库函数及其调用的java类软件包,因此对图像命名cid标签指向附件的方式较为复杂,CSDN中有大部分帖子是用python实现,未曾找到matlab方法。就在题主快要山穷水尽之时,又找到了这样一篇文章,里面提出可以将图片以base64编码的html代码进行邮件发送
(https://sendgrid.com/blog/embedding-images-emails-facts/)

base64是一个字符集,图片在html中可以通过base64编码为字符串,而不用通过http请求。但是这样做的缺点是图片越大,base64的字符串就会越长,导致发送的html代码越长,对网络带宽要求也更高。
在这里插入图片描述
python和java中自带了将文件转码为base64的库函数,但由于一开始选错了路,所以就只能硬着头皮走到黑了。
于是,我又找到了图片转base64编码工具,手动解码,自此大功告成。
在这里插入图片描述

解放双手——实现批量操作

我们最终的目的是为了实现内容相似,称呼不同的宣传推广邮件批量发送。现在终于可以开始施展拳脚了。
在配置好邮箱基本信息之后,读取一下待发送人员的名单,以变量receiverName和receiverEmail储存。

%接收者信息设置
receiver=readcell("xxxxx.xlsx"); %文件
receiver=string(receiver);
for i=1:length(receiver)-1
    receiverName(i,1)=receiver(i+1,1);
    receiverEmail(i,1)=receiver(i+1,2);
end

紧接着设置主题和内容,其中函数strjoin可以实现,字符串拼接功能,用换行符分隔html代码,避免一行的代码过长,再统一根据据换行符拼接在一起。

mailcontent=strjoin({
  '<html>'
  '<body>'
  '<h1>Hello, World!</h1>'
  ''
  '<h2>%s老师你好!</h2>'
  '<img src="图片的base64编码">'
  ''
  '</html>'
  '</body>'
  }, '\n');

sprintf函数可以实现字符替换的功能,在邮件内容的html代码中将称呼的地方改为%s 例如尊敬的%s老师,通过函数sprintf可以将%s处替换为变量receiverName(j)

mailcontent=strjoin({
  '<html>'
  '<body>'
  '<h1>Hello, World!</h1>'
  ''
  '<h2>%s老师你好!</h2>'
  '<img src="图片的base64编码">'
  ''
  '</html>'
  '</body>'
  }, '\n');

发送邮件:由于是批量发送,且数量一般较大,最好使用try…catch…的语法,当某一次因为邮箱信息错误、网络延迟等原因sendmail出现报错时能够跳过此次发送并记录下此次错误。

%发送邮件
    try
        sendmail_html(receiverEmail(j),mailtitle,mailcontent);
    catch
        error_count=error_count+1;
        error_index(j)="failed"; %记录失败邮件的索引
    end
    count=count-1;
end

完整代码:


%接收者信息设置
error_count=0;
error_index="  ";

receiver=readcell("xxxxxx.xlsx");
receiver=string(receiver);
for i=1:length(receiver)-1
    receiverName(i,1)=receiver(i+1,1);
    receiverEmail(i,1)=receiver(i+1,2);
end
%主题
mailtitle='xxxxxxxxxxxxxxx';

for j=1:length(receiverName)
%正文
mailcontent=sprintf(strjoin({
%此处放入html代码 以换行符分隔 避免一行过长 
%收件人昵称用%s代替
}"/n"),receiverName(j))

%发送邮件
    try
        sendmail_html(receiverEmail(j),mailtitle,mailcontent);
    catch
        error_count=error_count+1;
        error_index(j)="failed"; %记录失败邮件的索引
    end
    count=count-1;
end

面向小白——UI交互

既然都做到这了,那么就要面零基础的从业人员进行开发,设计交互界面,实现输入邮件名单自动发送并且可视化的功能,才是一款真正的产品。UI界面采用MATLAB AppDesigner进行设计。
在这里插入图片描述
左上角为发件人设置界面,输入发件人信息进行邮箱授权码验证,成功后才可登录。左下角为收件人设置,选择收件人名单,点击确认验证格式无误后即可在发送状态界面显示出待发送名单,同时可以显示出发送的状态。俗话说,程序里20%是在完成任务,80%是在预防可能出现的问题。这里面的细节还蛮多的,例如发送后在名单未发送完之前不可重复发送,发送完成后整理发送失败名单,可再次点击“发送”等。这些问题的发现与处理,就只能靠程序员明锐的直觉了…目前这款产品还未商用,仅供自娱自乐。

另附一张放风筝的照片,解放双手!
在这里插入图片描述

一点感想

近日,复旦大学一博士生用 ocr 和正则表达式帮助学院几分钟核查完数百人核酸完成截图的新闻,结合此次的发邮件工作,让我略有一些感想。
当然,我一定要为这位博士生点赞,能够解决一件实际的问题,切实提升工作效率,也有勇气承担起创新带来的风险。同样,我也在感概我国当前信息化教育还任重而道远,正如知乎某位答主所说,“在计算机行业,有非常多的手段可以让人们从繁重的工作中解放出来。”但是实际上,我们要走的路还很长。
在能力上,许多行业从业人员在能力上无法实现信息化的技术手段,比如编写程序、调用轮子或者是用简单的excel软件,导致他们工作内容的繁重。这也与我们小学、中学时期信息化教育的重视程度有关,没有经过系统学习和训练。
在意识上,对于非技术人员来说,企业以加班为荣的氛围或许会令他们更倾向于待在舒适区,以做繁重的工作为荣。而高效率解决问题,按时上下班,却被看作是一种摸鱼。对于技术人员而言,寻找一个新的技术手段,开发新的产品以此提升工作效率的同时意味着要承受更多的风险,解决一个问题的同时,也会带来更多新问题的隐患。就如此次的邮件系统,需要经过大量的测试才能真正作为商业产品交付使用,程序的bug很有可能造成邮件系统崩溃、商业信誉损失等问题。对于此问题,我们更需要企业的对创新的鼓励与扶持。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
抱歉,我是一个语言模型AI并没有具体的代码编写能力,但我可以提供给您一些参考信息。 一个裁缝店平台可以包含以下模块: 1. 用户模块:注册、登录、个人信息管理; 2. 订单模块:下单、查看订单、取消订单; 3. 商品模块:添加商品、查看商品; 4. 评论模块:用户可以对商品进行评价; 5. 财务模块:管理员可以查看订单收入、支出等财务信息。 可以使用 Oracle 数据库来存储用户、订单、商品、评论等相关信息。 以下是一个伪代码示例: 1. 创建用户表 CREATE TABLE Users ( UserId INT PRIMARY KEY, UserName VARCHAR(50), Password VARCHAR(50), Email VARCHAR(50), Phone VARCHAR(20) ); 2. 创建订单表 CREATE TABLE Orders ( OrderId INT PRIMARY KEY, UserId INT, OrderTime TIMESTAMP, ShippingAddress VARCHAR(100), TotalPrice INT, PaymentStatus VARCHAR(20), FOREIGN KEY (UserId) REFERENCES Users(UserId) ); 3. 创建商品表 CREATE TABLE Products ( ProductId INT PRIMARY KEY, ProductName VARCHAR(50), Description VARCHAR(200), Price INT, ImageUrl VARCHAR(100) ); 4. 创建评论表 CREATE TABLE Reviews ( ReviewId INT PRIMARY KEY, UserId INT, ProductId INT, ReviewTime TIMESTAMP, Rating INT, Comment VARCHAR(200), FOREIGN KEY (UserId) REFERENCES Users(UserId), FOREIGN KEY (ProductId) REFERENCES Products(ProductId) ); 5. 创建财务表 CREATE TABLE Finance ( FinanceId INT PRIMARY KEY, OrderId INT, Income INT, Expense INT, Profit INT, FOREIGN KEY (OrderId) REFERENCES Orders(OrderId) ); 通过以上伪代码示例,您可以大致了解一个裁缝店平台所需要的相关模块以及如何用 Oracle 数据库来存储相关信息。具体的实现细节需要根据具体的需求进行相应的开发

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值