2010-08-19 137 views
7

我最近创建了一个用于为我们的网站创建招聘发布的在线模板。一切都完成了,它在浏览器中正确格式化,自动发布到我们的网站,bla bla bla。通过PHP向动态创建的PDF发送电子邮件

我正在创建的最后一部分是为管理员提供一些选项,以一致,便捷的方式将发布内容分发到各个地方(通过电子邮件)。我创建了一个使用TCPDF库即时创建PDF文档的PHP页面。当加载pdf.php?id = X时,页面会显示一个包含作业发布X内容的PDF。这意味着我从不将PDF文件保存到服务器,只需在每次调用时即可创建它。

但是我想把这个PDF附加到电子邮件中,并发送给各个学院和内部邮件列表等。如果我将pdf.php?id = x附加到电子邮件中,它不会附加PDF,它附加了上面的名字,似乎是一个空白文件。

是否可以将其附加到电子邮件而不保存到服务器?


下面根据JM4的回应进一步解决问题添加下面。我已将PDF文件创建功能放入函数中,并将其放入包含文件中,以便更容易管理。

// random hash necessary to send mixed content 
$separator = md5(time()); 

$eol = PHP_EOL; 

// attachment name 
$filename = "_Desiredfilename.pdf"; 

include_once('pdf.php'); 
// encode data (puts attachment in proper format) 
$pdfdoc = job_posting_to_pdf($posting_id); 
$attachment = chunk_split(base64_encode($pdfdoc)); 

///////////HEADERS INFORMATION//////////// 
// main header (multipart mandatory) message 
$headers = "From: Sender_Name<[email protected]>".$eol; 
//$headers .= "Bcc: [email protected]".$eol; 
$headers .= "MIME-Version: 1.0".$eol; 
$headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol; 
$headers .= "Content-Transfer-Encoding: 7bit".$eol; 
$headers .= "This is a MIME encoded message.".$eol.$eol; 

// message 
$headers .= "--".$separator.$eol; 
$headers .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol; 
$headers .= "Content-Transfer-Encoding: 8bit".$eol.$eol; 
$headers .= $message.$eol.$eol; 

// attachment 
$headers .= "--".$separator.$eol; 
$headers .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol; 
$headers .= "Content-Transfer-Encoding: base64".$eol; 
$headers .= "Content-Disposition: attachment".$eol.$eol; 
$headers .= $attachment.$eol.$eol; 
$headers .= "--".$separator."--"; 

//Email message 
if(mail('[email protected]', 'test job posting', 'message body goes here', $headers)) { 
    echo 'mail sent'; 
} else { 
    echo 'error in email'; 
} 

这里是pdf.php的一个精简版:

function job_posting_to_pdf($job_id) { 
    require_once(ROOT . 'assets/libs/tcpdf/config/lang/eng.php'); 
    require_once(ROOT . 'assets/libs/tcpdf/tcpdf.php'); 
    // create new PDF document 
    $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); 

    // set document information 
    $pdf->SetCreator(PDF_CREATOR); 
    $pdf->SetAuthor(''); 
    $pdf->SetTitle('OPL Job Posting'); 
    $pdf->SetSubject('Job Posting'); 
    $pdf->SetKeywords('TCPDF, PDF, example, test, guide'); 

    // remove default header/footer 
    $pdf->setPrintHeader(false); 
    $pdf->setPrintFooter(false); 

    // set default monospaced font 
    $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); 

    //set margins 
    $pdf->SetMargins(11, PDF_MARGIN_TOP, 11); 

    //set auto page breaks 
    $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM); 

    //set image scale factor 
    $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); 

    //set some language-dependent strings 
    $pdf->setLanguageArray($l); 

    // --------------------------------------------------------- 

    $pdf->SetFont('times', 'I', 9); 
    $pdf->AddPage(); 

    $left_cell_width = 60; 
    $row_height = 6; 

    $pdf->Image(ROOT . 'assets/gfx/logos/OPL-Logo.jpg', 0, 5, null, 16, null, null, 'N', false, null,'R'); 
    $pdf->Ln('3'); 

    if(!$row['internal']) { 
     $pdf->Cell(0,0,'This position will be posted internally and externally, concurrently.',0,2,'C'); 
    } else { 
     $pdf->Cell(0,0,'Internal posting only.',0,2,'C'); 
    } 

    //Remainder of actual PDF creation removed to keep things simple 


    return $pdf->Output("", "S"); 
} 
+0

我们展示的代码(或最好是很砍倒骨架)。这听起来像你用来将URL转换为文件附件的方法是错误的。为什么你非常担心不要临时写文件? – symcbean 2010-08-19 21:51:14

+0

http://api.joomla.org/com-tecnick-tcpdf/TCPDF.html#methodOutput 我对dest使用'I'选项。我想知道如果S选项是我应该使用的。 – 2010-08-20 13:04:33

+0

做了任何答案在这里帮助你? – JM4 2010-09-02 16:30:26

回答

0

你可能也想看看通过PEAR Mail_Mime作为附件发送它。它可以接受附件作为一串数据。

RMail包看起来好像会通过stringAttachment类做同样的事情。你将不得不谷歌,因为我是一个新用户,所以我一次只能发布一个链接。

5

如果我完全理解你在问什么,这很简单。我假设你已经有使用类似fdpf或tcpdf生成的PDF。在这种情况下 - 简单地使用下面的代码:

<?php 
    // random hash necessary to send mixed content 
    $separator = md5(time()); 

    $eol = PHP_EOL; 

    // attachment name 
    $filename = "_Desiredfilename.pdf"; 

    // encode data (puts attachment in proper format) 
    $pdfdoc = $pdf->Output("", "S"); 
    $attachment = chunk_split(base64_encode($pdfdoc)); 

    ///////////HEADERS INFORMATION//////////// 
    // main header (multipart mandatory) message 
    $headers = "From: Sender_Name<[email protected]>".$eol; 
    $headers .= "Bcc: [email protected]".$eol; 
    $headers .= "MIME-Version: 1.0".$eol; 
    $headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol; 
    $headers .= "Content-Transfer-Encoding: 7bit".$eol; 
    $headers .= "This is a MIME encoded message.".$eol.$eol; 

    // message 
    $headers .= "--".$separator.$eol; 
    $headers .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol; 
    $headers .= "Content-Transfer-Encoding: 8bit".$eol.$eol; 
    $headers .= $message.$eol.$eol; 

    // attachment 
    $headers .= "--".$separator.$eol; 
    $headers .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol; 
    $headers .= "Content-Transfer-Encoding: base64".$eol; 
    $headers .= "Content-Disposition: attachment".$eol.$eol; 
    $headers .= $attachment.$eol.$eol; 
    $headers .= "--".$separator."--"; 


    //Email message 
    mail($emailto, $emailsubject, $emailbody, $headers); 

    ?> 
+0

你有正确的想法。这里的一切都有效,但是当它到达实际发送电子邮件的路线时,它似乎无限期地挂起。没有错误,没有任何东西。是否有可以传入的标题限制?这是一个超过810,000个字符(但它只是一个PDF页面)。 – 2010-09-02 18:59:13

+0

@Cory - 我的脚本有效。如果它挂起,你的pdf脚本有什么错误或不同。我已经使用上面的100页pdf没有问题。 标题的数量没有限制,可以传递。在编辑中发布您的实际代码,以便我们可以查看。 – JM4 2010-09-02 21:03:52

+0

感谢JM4,我在原帖中添加了代码。 就像我说的,它会做一切事情,但实际的mail()调用。所以我可以输出$ header通过回声没有probs。 – 2010-09-03 13:05:12

1

我必须想出解决办法,我的眼球都被最终肯定疼......

1)您需要安装PHPMailer到PHP服务器。

2)包含的PHPMailer的类在TCPDF脚本,像这样(你的路径可能会有所不同):

require_once('../PHPMailer_v5.1/class.phpmailer.php'); 

3)现在,经过您的PDF的代码只是跟PHPMailer的,像这样:

$filename = "custompdf_$name_$time.pdf"; 

$pdf->Output($filename, 'F'); // save the pdf under filename 

$mail = new PHPMailer(); $mail->IsSMTP(); 

$mail->Host = "mail.yourhost.com"; 
$mail->SMTPAuth = true;     // enable SMTP authentication 
$mail->Port  = 26;     // set the SMTP port for the GMAIL server 
$mail->Username = "user+yourhost.com"; // SMTP account username 
$mail->Password = "topsecret";  // SMTP account password 

$mail->From = "[email protected]"; 
$mail->FromName = "Stack Overflower"; 
$mail->AddAddress($email, $name); // in this case the variable has been passed 
$mail->AddCC("[email protected]", "Johnny Person"); // in this case we just hard code it 
$mail->SMTPDebug = 0; // use 2 for debugging the email send 

$pdf_content = file_get_contents($filename); 

$mail->WordWrap = 50; 
$mail->AddStringAttachment($pdf_content, "custompdf_for_$name_$time.pdf", "base64", "application/pdf"); // note second item is name of emailed pdf 
$mail->IsHTML(true); 
$mail->Subject = "Your pdf is here"; 
$mail->Body = "Dear $name,<br> 
Here is your custom generated pdf generated at $t.<br><br> 
Thank you"; 
if(!$mail->Send()) { 
    echo "Sorry ... EMAIL FAILED"; 
    } else { echo "Done. . . Email sent to $email at $t."; } 

unlink($filename); // this will delete the file off of server 

当然,你有很多选择来发送电子邮件,比如不使用html,或者同时发送html和文本,添加许多收件人和/或cc等等。

编辑:这不会暂时保存在服务器上的文件,但它会自行清理之后与unlink命令。

+0

您的解决方案意味着他需要将PHP Mailer脚本上传到他的目录,而不是这种情况。简单的PHP邮件()命令将发送电子邮件。你也不需要保存PDF文件,因为它可以工作得很好,就像$ pdf-> Output($ filename,'S'); – JM4 2010-09-07 14:30:44

+0

谢谢 - 实际上,虽然邮件工作,phpmailer是更好的方式,即我需要验证SMTP功能。我想'S'选项会将临时工作保存在内存中,而不是作为磁盘上的实际文件...如果您可以提供一个工作示例...我无法打开流错误。 – Mischa 2010-09-08 09:13:16

0

我同意使用邮件库来代替使用默认的mail()函数手动构建mime消息。 SwiftMailer是另一个很好的开源PHP邮件库。这里的sample code用于使用动态内容作为附件,而不必首先将其保存到文件系统。

0

你的头似乎有点出:

  • application/octet-stream应该成为application/octetstream

  • Content-Disposition: attachment ..应该成为Content-Disposition: attachment; filename="' . basename($filename) . '"

继承人的attachement标题应该是什么样子:

// attachment 
$headers .= "--".$separator.$eol; 
$headers .= "Content-Type: application/octetstream;".$eol; //Fixed 
$headers .= "Content-Transfer-Encoding: base64".$eol; 
$headers .= 'Content-Disposition: attachment; filename="' . basename(filename).'"'.$eol; 
$headers .= 'Content-ID: <' . basename($filename) . '>' . $eol . $eol //EOL X2 Before 
$headers .= $attachment; 

//Run the above in a loop for multiple attachments, after add the final line 
$headers .= '--' . $separator . '--' . $eol; 

这是从我工作的应用程序之一采取继承人的循环,如果你想看到它:

foreach ($this->attachments as $attachment) { 
    if (file_exists($attachment['file'])) { 
     $handle = fopen($attachment['file'], 'r'); 
     $content = fread($handle, filesize($attachment['file'])); 

     fclose($handle); 

     $message .= '--' . $boundary . $this->newline; 
     $message .= 'Content-Type: application/octetstream' . $this->newline; 
     $message .= 'Content-Transfer-Encoding: base64' . $this->newline; 
     $message .= 'Content-Disposition: attachment; filename="' . basename($attachment['filename']) . '"' . $this->newline; 
     $message .= 'Content-ID: <' . basename($attachment['filename']) . '>' . $this->newline . $this->newline; 
     $message .= chunk_split(base64_encode($content)); 
    } 
} 
$message .= '--' . $boundary . '--' . $this->newline; 
+0

如果pdf在服务器上不存在,但是通过带有tcpdf的url,你会怎么做? – Alex 2014-01-20 11:22:08