将 DOCX 编码为通过电子邮件发送

Posted

技术标签:

【中文标题】将 DOCX 编码为通过电子邮件发送【英文标题】:Encoding DOCX to be Sent via email 【发布时间】:2012-10-01 15:24:08 【问题描述】:

我正在编写一个小的 Perl 应用程序来在我工作的内部发送电子邮件,但我遇到了附件问题。现在,我可以听到你们所有人都在尖叫“使用 MIME::Lite”,但这并不是那么容易 - 管理规则告诉我,我无法使用 cpan 中的任何东西......

无论如何,我正在使用 MIME::Base64 对我发送的任何附件进行编码。我在电子邮件方面使用 Net::SMTP。

编码是这样完成的(直接从 Perldoc 页面出来):

my $encoded = "";
use MIME::Base64 qw(encode_base64);
open (FILE, "7857084216_9816ae9bec_b.jpg") or die "$!\n";
while (read(FILE, $buf, 60*57)) 
$encoded .= encode_base64($buf);

相关的Net::SMTP代码如下:

use Net::SMTP;
$smtp = Net::SMTP->new("mailserver",
                Hello => 'somedomain.com.au',
                Timeout => 60,
                Debug => 0,
                );
$smtp->mail(<services\@somedomain.com.au>);
$smtp->to(<me\@somedomain.com.au>);
$smtp->cc(<another\@somedomain.com.au>);
$smtp->data();
$smtp->datasend("Subject: testing 123\n");
$smtp->datasend("To: me\@somedomain.com.au\n");
$smtp->datasend("CC: another\@somedomain.com.au\n");
$smtp->datasend("MIME-Version: 1.0\n");
$smtp->datasend("Content-type: multipart/mixed;\n\tboundary=\"$boundary\"\n");
$smtp->datasend("--$boundary\n");
$smtp->datasend("Content-type: text/html; charset=utf-8\n");
$smtp->datasend("\n");
$smtp->datasend("<p> Test Email!</p>\n");
$smtp->datasend("\n");
$smtp->datasend("--$boundary\n");
$smtp->datasend("Content-type: image/jpeg; name=\"7857084216_9816ae9bec_b.jpg\"\n");
$smtp->datasend("Content-ID: \n");
$smtp->datasend("Content-Disposition: attachment; filename=\"7857084216_9816ae9bec_b.jpg\"\n");
$smtp->datasend("Content-transfer-encoding: base64\n");
$smtp->datasend("\n");
$smtp->datasend("$encoded");
$smtp->datasend("\n");
$smtp->datasend("--$boundary--\n");
$smtp->dataend;
$smtp->quit;

此时,我将这些电子邮件发送给自己并使用 Outlook 2010 阅读它们 发送图像(例如 jpeg)时,我根本没有任何问题 - 据我所知,一切似乎都在逐字节解码。 当我发送纯文本的 docx 类型文件时,一切似乎都很好。 但是,当我发送插入了图像的 docx 文件时,文件已损坏。

不是邮件发送和附件方面的专家,我有点茫然。我应该如何编码 docx 文件以附加到电子邮件?任何帮助将不胜感激!

另外忘了提一下,我已经尝试相应地设置内容类型:内容类型:application/vnd.openxmlformats-officedocument.wordprocessingml.document

【问题讨论】:

文件究竟是如何损坏的?它们根本没有打开,或者缺少什么? 您可以编辑您的问题(编辑链接在标签下方)。但是你没有回答我的评论。 Petr,这取决于 - 通常在 Word 中打开它们时,我收到一条错误消息,告诉我“文件已损坏,无法打开”。在那条消息之后,我收到“Word 在“file.docx”中发现不可读的内容。你想恢复......”。有时当我尝试恢复时,它可以正常工作,但有时会失败。 您是否验证了文件使用base64 正确编码?尝试在编码之后进行解码。文件类型应该与结果完全无关,AFAIK。 我猜文件类型是一个红鲱鱼,当文件变得太大时,你会遇到一些大小限制。如果你的 base64 数据都在一个可怕的行上,用换行符换行。 (无论如何,您的编码循环都可以使用大修;它看起来效率很低。) 【参考方案1】:

我以前见过这种情况,通常归结为不正确的 mime 类型或 mime 结构。您提到您尝试添加 mime 类型,因此这可能表明 mime 结构可能有点偏离。我已经在 xslx 和 csv 文件中看到了这一点。 CSV 会出现,因为解码器假定文本,但如果您没有正确的二进制数据 Mime,它将始终尝试转换为 ascii。我在 xslx 与 docx 中意识到这一点,但我认为同样的原则也适用。

这是我正在生成的示例电子邮件的片段(使用 Mime:Lite),但可能会有所帮助。

    From: me@example.com
To: example@example.com
Subject: Example
Content-Transfer-Encoding: binary
Content-Type: multipart/mixed; boundary="_----------=_13433203262384120"


--_----------=_13433203262384120
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html
Content-Disposition: inline

<body>Hello,<br>
<p>EMAIL BODY</p>
<p>Thanks,<br>&nbsp;&nbsp;Blah</body>

--_----------=_13433203262384120
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; name="sample.xlsx"
Content-Disposition: attachment; filename="sample.xlsx"
Content-Transfer-Encoding: base64

UEsDBBQAAAAIAAFk+kDm/EEvVgEAACQFAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbMVUS28CIRC+
N+l/IFybXdRD0zSuHvo4tia1P4DC6BJZIAxa/fed3a32EesjmvQCgfleQ8j0h8vKsgVENN4VvJt3
OAOnvDZuWvDX8WN2wxkm6bS03kHBV4B8OLi86I9XAZAR22HBy5TCrRCoSqgk5j6Ao8rEx0omOsap
CFLN5BREr9O5Fsq7BC5lqdbgg/49TOTcJvawpOs2SQSLnN21wNqr4DIEa5RMVBcLp3+5ZJ8OOTEb
DJYm4BUBOBNbLZrSnw5r4jM9TjQa2EjG9CQrggnt1Sj6gIII+W6ZLUH9ZGIUkMa8IkoOdSINOgsk
CTEZ+Eq901z5CMe7r5+pZh9qubQC08oCntwshghSYwmQKpu3ovusE30qaNfuyQEamX2O7z7O3ryf
....  <Snipped>
ZRQyppbEwDToT079O3NfFSgofVlmcbvM34PqkQQdCmrLiWYxleokviz25OPYvpRw/s64avTwn+uh
SSg4ctedMMaTkj47g3IXX1BLAQIUAxQAAAAIAAFk+kDm/EEvVgEAACQFAAATAAAAAAAAAAEAAAC2
gQAAAABbQ29udGVudF9UeXBlc10ueG1sUEsBAhQDFAAAAAgAAWT6QPWzn3yRAQAAQAMAABAAAAAA
AAAAAQAAALaBhwEAAGRvY1Byb3BzL2FwcC54bWxQSwECFAMUAAAACAABZPpAkg6xSFoBAAC2AgAA
EQAAAAAAAAABAAAAtoFGAwAAZG9jUHJvcHMvY29yZS54bWxQSwECFAMUAAAACAABZPpAyfySzFpy
BAAcqRgAFAAAAAAAAAABAAAAtoHPBAAAeGwvc2hhcmVkU3RyaW5ncy54bWxQSwECFAMUAAAACAAB
ZPpARQtWMQgCAABaBQAADQAAAAAAAAABAAAAtoFbdwQAeGwvc3R5bGVzLnhtbFBLAQIUAxQAAAAI
AABk+kCVKtbcsAEAAFgDAAAPAAAAAAAAAAEAAAC2gY55BAB4bC93b3JrYm9vay54bWxQSwECFAMU
AAAACAABZPpA8XOrpLUFAABVGwAAEwAAAAAAAAABAAAAtoFrewQAeGwvdGhlbWUvdGhlbWUxLnht
bFBLAQIUAxQAAAAIAO1j+kD+7E73UA8AAM1zAAAYAAAAAAAAAAEAAAC2gVGBBAB4bC93b3Jrc2hl
ZXRzL3NoZWV0MS54bWxQSwECFAMUAAAACAAAZPpA7/olcLO/MgAHxsABGAAAAAAAAAABAAAAtoHX
kAQAeGwvd29ya3NoZWV0cy9zaGVldDIueG1sUEsBAhQDFAAAAAgAAWT6QCFo34b0AAAATgMAABoA
AAAAAAAAAQAAALaBwFA3AHhsL19yZWxzL3dvcmtib29rLnhtbC5yZWxzUEsBAhQDFAAAAAgAAWT6
QIB6g4TsAAAAUQIAAAsAAAAAAAAAAQAAALaB7FE3AF9yZWxzLy5yZWxzUEsFBgAAAAALAAsAxgIA
AAFTNwAAAA==


--_----------=_13433203262384120--

【讨论】:

感谢您的回复。我原以为使用正确的内容类型应该会有所作为,但根据我今天/昨天的经验,除非我将其指定为 application/octet-stream(根据我上面的回答)。干杯【参考方案2】:

我发现了这个问题,“内容类型”似乎确实有所作为。根据我的发现,我将所有包含 Base64 编码数据的 Content-type 调用替换为以下内容:

Content-type: application/octet-stream;

这似乎已经直接发送了,Outlook 2010 和 2003 都没有问题。我已经针对二进制文件、纯文本等进行了测试,在我当前的环境中似乎一切正常。

干杯

【讨论】:

以上是关于将 DOCX 编码为通过电子邮件发送的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python 发送 .docx 附件

使用 MYSQL db 中的正文通过 PHP 发送电子邮件并解析 \n

查询将查询转换为HTML并通过电子邮件发送

您如何通过电子邮件发送到 CL 中的用户列表?

使用 EWS API 发送电子邮件时控制消息编码

Outlook 未显示 UTF-8 编码文本 (یب سائٹ Ù) 通过 php 邮件发送的电子邮件