ฉันกำลังพยายามสร้าง PDF สำหรับใบเสร็จรับเงินการสั่งซื้อทันทีจาก HTML ที่สร้างขึ้นทันที จากนั้นจึงส่งอีเมลถึงบุคคลอื่น
ฉันไม่ต้องการสร้างไฟล์จริงๆ แนบไปกับอีเมลแล้วลบไฟล์ ดังนั้นฉันจึงพยายามส่ง html ไปยัง wkhtmltopdf ผ่าน STDIN (จาก Perl) จากนั้นจับเอาต์พุต PDF จาก wkhtmltopdf ในอีเมล ไฟล์แนบโดยใช้ MIME::Lite Email::Mime
ใช้งานได้อย่างสมบูรณ์ โดยใช้ Perl เพื่อให้ผู้คนดาวน์โหลดไฟล์ PDF ที่สร้างขึ้นแบบไดนามิกจากเว็บไซต์ของฉัน แต่พยายามใช้กับ MIME::Lite Email::Mime ไม่ได้' ไม่ทำงาน (มันอาจจะได้ผล แต่เนื่องจากมันล้าสมัยแล้ว เราเลยใช้ Email::Mime แทน)
ฉันแน่ใจอย่างยิ่งว่านี่เป็นเพราะฉันขาดความเข้าใจพื้นฐานในการทำงานกับตัวจัดการไฟล์ ไปป์ backticks และสิ่งอื่นๆ ที่ไม่ค่อยได้ใช้ และฉันก็อยากจะเข้าใจสิ่งเหล่านี้ให้มากขึ้น
นี่คือสิ่งที่ได้ผล:
#!/usr/bin/perl
#### takes string containing HTML and outputs PDF to browser to download
#### (otherwise would output to STDOUT)
print "Content-Disposition: attachment; filename='testPDF.pdf'\n";
print "Content-type: application/octet-stream\n\n";
my $htmlToPrint = "<html>a bunch of html</html>";
### open a filehandle and pipe it to wkhtmltopdf
### *the arguments "- -" tell wkhtmltopdf to get
### input from STDIN and send output to STDOUT*
open(my $makePDF, "|-", "wkhtmltopdf", "-", "-") || die("$!");
print $makePDF $htmlToPrint; ## sends my HTML to wkhtmltopdf which streams immediately to STDOUT
exit 1;
คุณสามารถเรียกใช้สิ่งนี้ได้จาก Apache และจะแสดงกล่องโต้ตอบการดาวน์โหลดแก่ผู้ใช้ และดาวน์โหลดไฟล์ PDF ที่ถูกต้องที่อ่านได้ซึ่งมีชื่อว่า 'testPDF.pdf'
แก้ไข: วิธีแก้ไขคือโมดูล Capture::Tiny (และ อีเมล::Mime):
#!/usr/bin/perl
use Capture::Tiny qw( capture );
use Email::Sender::Simple;
use Email::MIME::Creator;
my $htmlToPrint = "<html>a bunch of html</html>";
### it's important to capture STDERR as well, since wkhtmltopdf outputs
### its console messages on STDERR instead of STDOUT, so it can output
### the PDF to STDOUT; otherwise it will spam your error log
(my $pdfstream, my $consoleOutput, my @retvals) = capture {
open(my $makePDF, "|-", "wkhtmltopdf", "-", "-") || die("$!");
print $makePDF $htmlToPrint;
};
my @parts = (
Email::MIME->create(
attributes => {
content_type => "text/plain",
disposition => "inline",
charset => "US-ASCII",
encoding => "quoted-printable",
},
body_str => "Your order receipt is attached as a PDF.",
),
Email::MIME->create(
attributes => {
filename => "YourOrderReceipt.pdf",
content_type => "application/pdf",
disposition => "attachment",
encoding => "base64", ## base64 is ESSENTIAL, binary and quoted-printable do not work!
name => "YourOrderReceipt.pdf",
},
body => $pdfstream,
),
);
my $email = Email::MIME->create(
header_str => [
From => 'Some Person <[email protected]>',
To => '[email protected]',
Subject => "Your order receipt is attached...",
],
parts => [ @parts ],
);
Email::Sender::Simple->send($email);
exit 1;
ทั้งหมดนี้ทำงานได้อย่างสมบูรณ์แบบในขณะนี้
ปัญหาส่วนใหญ่ดูเหมือนว่า wkhtmltopdf ไม่ได้บัฟเฟอร์เอาต์พุต PDF และส่งทีละบรรทัด มันจะสตรีมเอาต์พุต PDF ทั้งหมดไปยัง STDOUT ทันทีที่ได้รับอินพุต HTML จาก STDIN
ฉันคิดว่านี่คือสาเหตุที่ฉันไม่สามารถเปิด open2 หรือ open3 ได้
ฉันลอง open (my $pdfOutput, "echo \"$htmlToPrint\"| wkhtmltopdf - -|")
ด้วย แต่สิ่งนี้ทำงานในเชลล์ ดังนั้นถึงแม้จะมี $htmlToPrint
อยู่ในเครื่องหมายคำพูด คำสั่งก็ยังควบคุมสัญลักษณ์ที่ใช้ใน HTML
หวังว่าบางคนพบว่าสิ่งนี้มีประโยชน์ ...
MIME::Lite
ไม่แนะนำให้ใช้MIME::Lite
- person jordanm   schedule 30.01.2013MIME::Lite
น่าจะได้ผลเช่นกัน แต่ฉันคิดว่าการใช้Email::MIME
ที่ใหม่กว่าที่แนะนำนั้นเป็นสิ่งที่ดี ปัญหาคือคุณไม่สามารถสื่อสารแบบสองทิศทางกับไปป์ได้ คุณต้องมีโมดูลเช่นCapture::Tiny
ไฟล์แนบอีเมลต้องมีการเข้ารหัสbase64
จึงจะทำงานได้ พยายามbinary
และquoted-printable
แล้วไม่มีผล - person waldo22   schedule 02.02.2013