Saya mencoba membuat PDF untuk tanda terima pesanan dengan cepat dari HTML yang juga dibuat dengan cepat, lalu mengirimkannya melalui email ke seseorang.
Saya benar-benar tidak ingin membuat file, melampirkannya ke email, lalu menghapus file tersebut, jadi saya mencoba mengirim html ke wkhtmltopdf melalui STDIN (dari Perl) dan kemudian menangkap output PDF dari wkhtmltopdf di email lampiran menggunakan MIME::Lite Email::Mime.
Ini benar-benar berfungsi menggunakan Perl untuk memungkinkan orang mengunduh file PDF yang dihasilkan secara dinamis dari situs web saya, tetapi mencoba menggunakannya dengan MIME::Lite Email::Mime tidak berhasil tidak berfungsi. (mungkin akan berhasil, tapi karena sudah ketinggalan zaman, kami menggunakan Email::Mime sebagai gantinya)
Saya benar-benar yakin bahwa hal ini disebabkan oleh kurangnya pemahaman mendasar saya dalam bekerja dengan filehandle, pipa, backticks, dan hal-hal lain yang jarang digunakan, dan saya ingin lebih memahami hal-hal ini.
Inilah yang berhasil:
#!/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;
Anda dapat menjalankan ini apa adanya dari Apache, dan ini akan menampilkan dialog pengunduhan kepada pengguna dan mengunduh pdf yang benar dan dapat dibaca bernama 'testPDF.pdf'.
EDIT: Solusinya adalah modul Capture::Tiny (dan Email::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;
Ini semua berfungsi dengan baik sekarang.
Sebagian besar masalahnya adalah wkhtmltopdf tidak menyangga keluaran PDF dan mengirimkannya baris demi baris; itu segera mengalirkan semua keluaran PDF ke STDOUT segera setelah mendapat masukan HTML dari STDIN.
Saya rasa inilah sebabnya saya tidak dapat mengaktifkan open2 atau open3.
Saya juga mencoba open (my $pdfOutput, "echo \"$htmlToPrint\"| wkhtmltopdf - -|")
, tetapi ini berjalan di shell, jadi meskipun $htmlToPrint
diapit tanda kutip, perintah tersebut tersedak pada simbol yang digunakan dalam HTML.
Semoga seseorang menganggap ini bermanfaat...
MIME::Lite
merekomendasikan untuk tidak menggunakanMIME::Lite
. - person jordanm   schedule 30.01.2013MIME::Lite
akan berhasil juga, tetapi menurut saya menggunakanEmail::MIME
yang lebih baru dan direkomendasikan adalah Hal yang Baik. Masalahnya adalah Anda tidak dapat melakukan komunikasi dua arah dengan pipa; Anda memerlukan modul sepertiCapture::Tiny
. Lampiran email juga harus dikodekanbase64
agar dapat berfungsi. Mencobabinary
danquoted-printable
tidak berpengaruh. - person waldo22   schedule 02.02.2013