很多公司都有这样的需求,希望系统可以定时邮件发送一些统计报表给到相关人员,以便做数据分析,或者是希望做单时,发送单据内容给到相关人员提醒审核和备案,下面分享一种十分简单方便的实现方式,javamail+4gl+perl脚本实现;
1:在aooi999配置好系统标准的javamail 功能,测试可以正常发送报表邮件,配置方式可以百度
2:添加邮件发送功能函数,可以参考cl_prt里面的发邮件功能,我简化了一些东西代码如下:
FUNCTION p_sendmail1(l_xml)
DEFINE p_chk LIKE type_file.chr100
DEFINE l_cmd STRING
DEFINE l_top STRING
DEFINE l_tempdir STRING
DEFINE res LIKE type_file.num5
DEFINE l_xml RECORD
file STRING, #XML檔名(不含路徑,檔案放置在os.Path.join(FGL_GETENV("TEMPDIR")底下)
mailserver STRING, #MAIL SERVER IP
serverport STRING, #MAIL SERVER Port
user STRING, #MAIL SERVER User
passwd STRING, #MAIL SERVER User Password
checkauth LIKE type_file.chr1, #No.FUN-690005 VARCHAR(1), #CheckAuth
subject STRING, #信件主旨
body STRING, #信件本文內容檔路徑
attach STRING, #信件附件檔路徑
recipient STRING, #收件者
cc STRING, #副本
bcc STRING, #密件副本
sender STRING #寄件者
END RECORD
DEFINE l_mlj RECORD LIKE mlj_file.*
DEFINE l_str STRING
DEFINE lc_channel base.Channel
DEFINE
ch base.Channel,
l_status SMALLINT,
l_index SMALLINT,
l_temp STRING,
l_text STRING
LET res = 1
{INITIALIZE l_mlj.* TO NULL
SELECT * INTO l_mlj.* FROM mlj_file WHERE mlj01 = "DEFAULT"
INITIALIZE l_xml.* TO NULL
LET l_top = fgl_getenv("TOP")
LET l_tempdir =fgl_getenv("TEMPDIR")
# 生成XML文件写入系统
LET l_xml.file = p_chk CLIPPED,'.xml' #按传入的名称
LET l_xml.mailserver = l_mlj.mlj03 #邮件主机
LET l_xml.serverport = l_mlj.mlj04 #邮件主机端口
LET l_xml.user = l_mlj.mlj05 #邮件主机用户
LET l_xml.passwd = l_mlj.mlj06 #邮件主机密码
LET l_xml.checkauth = l_mlj.mlj08 #认证
LET l_xml.sender = 'caozq@test.com' #寄件人
LET l_xml.subject ='TEST' #邮件主旨
LET l_xml.body = l_tempdir CLIPPED,'/',p_body CLIPPED #文本内容
LET l_xml.attach = l_tempdir CLIPPED,'/',p_attach CLIPPED #附件地址
LET l_xml.recipient = '839438304@qq.com' #收件人
#LET l_xml.cc = g_xml.cc
#LET l_xml.bcc = g_xml.bcc}
#########產生for javamail的xml檔############
LET l_tempdir =fgl_getenv("TEMPDIR")
LET l_top = fgl_getenv("TOP")
LET lc_channel = base.Channel.create()
LET l_str = os.Path.join(l_tempdir CLIPPED,l_xml.file CLIPPED)
CALL lc_channel.openFile(l_str, "w")
CALL lc_channel.setDelimiter("")
CALL lc_channel.write("<?xml version=""1.0"" encoding=""UTF-8""?>") #No.FUN-740189
CALL lc_channel.write("<Mail>")
CALL lc_channel.write("<Protocol>smtp</Protocol>")
LET l_str = '<CheckAuth>',l_xml.checkauth CLIPPED,'</CheckAuth>'
CALL lc_channel.write(l_str CLIPPED)
LET l_str = '<MailServer>',l_xml.mailserver CLIPPED,'</MailServer>'
CALL lc_channel.write(l_str CLIPPED)
LET l_str = '<MailServerPort>',l_xml.serverport CLIPPED,'</MailServerPort>'
CALL lc_channel.write(l_str CLIPPED)
LET l_str = '<MailServerUser>',l_xml.user CLIPPED,'</MailServerUser>'
CALL lc_channel.write(l_str CLIPPED)
LET l_str = '<MailServerUserPassword>',l_xml.passwd CLIPPED,'</MailServerUserPassword>'
CALL lc_channel.write(l_str CLIPPED)
Let l_str = '<Subject>',l_xml.subject CLIPPED,'</Subject>'
CALL lc_channel.write(l_str CLIPPED)
IF NOT cl_null(l_xml.body) THEN
LET l_str = '<MessageBody>',l_xml.body CLIPPED,'</MessageBody>'
CALL lc_channel.write(l_str CLIPPED)
END IF
IF NOT cl_null(l_xml.attach) THEN
LET l_str = '<Attach>',l_xml.attach CLIPPED,'</Attach>'
CALL lc_channel.write(l_str CLIPPED)
END IF
LET l_str = '<Recipient>',l_xml.recipient CLIPPED,'</Recipient>'
CALL lc_channel.write(l_str CLIPPED)
IF NOT cl_null(l_xml.cc) THEN
LET l_str = '<CCRecipient>',l_xml.cc CLIPPED,'</CCRecipient>'
CALL lc_channel.write(l_str CLIPPED)
END IF
IF NOT cl_null(l_xml.bcc) THEN
LET l_str = '<BCCRecipient>',l_xml.bcc CLIPPED,'</BCCRecipient>'
CALL lc_channel.write(l_str CLIPPED)
END IF
LET l_str = '<From>',l_xml.sender CLIPPED,'</From>'
CALL lc_channel.write(l_str CLIPPED)
CALL lc_channel.write("</Mail>")
CALL lc_channel.close()
#將產生給javamail的xml檔轉成客戶端的編碼
# 生成XML文件写入系统
LET l_cmd="chmod 777 ",os.Path.join(l_tempdir CLIPPED,l_xml.file CLIPPED)," 2>/dev/null" #FUN-8B0011
RUN l_cmd
LET l_cmd="sh ",l_top CLIPPED,"/ds4gl2/bin/javamail/UnixMailSender.bat ",
os.Path.join(l_tempdir CLIPPED,l_xml.file CLIPPED)," >/u1/out/caozq.txt" #FUN-510006 FUN-8B0011
RUN l_cmd IN FORM MODE RETURNING res
if res = 0 then
let l_str = "Send ok"
else
let l_str = "Send fail"
end if
#读取caozq.txt,判断是否成功
SLEEP 1
LET ch = base.Channel.create()
CALL ch.openFile('/u1/out/caozq.txt','r')
LET l_status = ch.read(l_temp)
WHILE l_status
LET l_text = l_text.trim(),l_temp.trim()
LET l_status = ch.read(l_temp)
END WHILE
LET l_index = 0
LET l_index = l_text.getIndexOf('successfully',1)
IF l_index > 0 THEN
let l_str = "Send ok"
else
let l_str = "Send fail"
END IF
END FUNCTION
代码可以独立做一个公用函数,其他函数调用的时候只需要传入g_xml数组就能实现自动发邮件了
下面是例子
#######################################
#apmt540采购单发出时自动发邮件给供应商#
#######################################
FUNCTION p_sendmail_apmt540(p_prog,p_docno)
DEFINE p_prog LIKE type_file.chr100
DEFINE p_docno LIKE type_file.chr100
DEFINE lc_channel base.Channel
DEFINE l_pmn RECORD
pmn01 LIKE pmn_file.pmn01,
pmn02 LIKE pmn_file.pmn02,
pmn04 LIKE pmn_file.pmn04,
ima02 LIKE ima_file.ima02,
ima021 LIKE ima_file.ima021,
pmn20 LIKE pmn_file.pmn20,
pmn07 LIKE pmn_file.pmn07
END RECORD
DEFINE l_xml RECORD
file STRING, #XML檔名(不含路徑,檔案放置在os.Path.join(FGL_GETENV("TEMPDIR")底下)
mailserver STRING, #MAIL SERVER IP
serverport STRING, #MAIL SERVER Port
user STRING, #MAIL SERVER User
passwd STRING, #MAIL SERVER User Password
checkauth LIKE type_file.chr1, #No.FUN-690005 VARCHAR(1), #CheckAuth
subject STRING, #信件主旨
body STRING, #信件本文內容檔路徑
attach STRING, #信件附件檔路徑
recipient STRING, #收件者
cc STRING, #副本
bcc STRING, #密件副本
sender STRING #寄件者
END RECORD
DEFINE l_mlj RECORD LIKE mlj_file.*
DEFINE l_tempdir STRING
DEFINE l_str STRING
DEFINE l_filename LIKE type_file.chr1000
DEFINE l_xls LIKE type_file.chr1000
DEFINE l_chr VARCHAR(8000)
DEFINE l_cmd VARCHAR(8000)
INITIALIZE l_xml.* TO NULL
INITIALIZE l_mlj.* TO NULL
SELECT * INTO l_mlj.* FROM mlj_file WHERE mlj01 = "DEFAULT"
LET l_tempdir =fgl_getenv("TEMPDIR")
#生成附件程序
LET l_filename = p_docno CLIPPED,'.txt'
LET l_xls = p_docno CLIPPED,'.xls'
LET lc_channel = base.Channel.create()
LET l_str = os.Path.join(l_tempdir CLIPPED,l_filename CLIPPED)
CALL lc_channel.openFile(l_str, "w")
CALL lc_channel.setDelimiter("")
CALL lc_channel.write("采购单号|*|项次|*|料件编号|*|品名|*|规格|*|数量|*|单位")
DECLARE caozq_01 CURSOR FOR
SELECT pmn01||'|*|'||pmn02||'|*|'||pmn04||'|*|'||ima02||'|*|'||ima021||'|*|'||pmn20||'|*|'||pmn07 FROM pmn_file,ima_file where pmn04=ima01 AND pmn01=p_docno
FOREACH caozq_01 INTO l_chr
CALL lc_channel.write(l_chr CLIPPED)
END FOREACH
CALL lc_channel.close()
#将文件转换成xls
LET l_cmd = "/u1/topprod/topcust/czz/4gl/txt2xlszqcao.pl "||l_tempdir CLIPPED,'/',l_filename CLIPPED ||" "||l_tempdir CLIPPED,'/',l_xls CLIPPED||" " #转换xls
RUN l_cmd
#生成之后,调用mail 发送
LET l_xml.file =p_prog CLIPPED,p_docno CLIPPED #XML文件名称
LET l_xml.mailserver = l_mlj.mlj03 #邮件主机
LET l_xml.serverport = l_mlj.mlj04 #邮件主机端口
LET l_xml.user = l_mlj.mlj05 #邮件主机用户
LET l_xml.passwd = l_mlj.mlj06 #邮件主机密码
LET l_xml.checkauth = l_mlj.mlj08 #认证
LET l_xml.sender = 'caozq@xxx.com' #寄件人
LET l_xml.subject =p_docno,'采购单' #邮件主旨
LET l_xml.body = 'test' CLIPPED #文本内容
LET l_xml.attach = l_tempdir CLIPPED,'/',l_xls CLIPPED #附件地址
LET l_xml.recipient = '839438304@qq.com' #收件人
#LET l_xml.cc = g_xml.cc
#LET l_xml.bcc = g_xml.bcc
CALL p_sendmail1(l_xml.*)
END FUNCTION
里面写的是将数据抓取出来后,先以字串形式写入到一个txt文档,最后通过perl转换成EXCEL档,再将以附件的形式发送到指定收件人,嗯,就是这样!
附上perl脚本代码:
#!/usr/bin/perl -w
use strict;
use Spreadsheet::WriteExcel;
#use Text::CSV::Encoded;
use Encode;
if (($#ARGV < 1) || ($#ARGV > 2)) {
die("Usage: csv2xls txtfile.txt newfile.xls\n");
};
my $workbook = Spreadsheet::WriteExcel->new($ARGV[2]);
# Open the Comma Separated Variable file
open CSVFILE, '<:utf8', $ARGV[0] or die "$ARGV[0]: $!";
my $worksheet = $workbook->add_worksheet('Scrap_list');
my $row = 0;
$worksheet->set_column(0,5,14);
while (<CSVFILE>) {
s/[\001-\037]//g;
my @list = split /\|\*\|/,$_;
my $col = 0;
foreach my $token (@list) {
if ($token=~/^0[^.]/) {
$worksheet->write_string($row, $col, $token );
}
else
{
$worksheet->write($row, $col, $token);
}
$col++;
}
$row++;
}
close(CSVFILE);
$workbook->close();
©著作权归作者所有:来自51CTO博客作者四方木的原创作品
转载请注明:赫非域 » tiptop自定义发送邮件