Windows wkhtmltopdf support

flebas - July 16, 2009 - 23:06
Project:Printer, e-mail and PDF versions
Version:6.x-1.7
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:postponed (maintainer needs more info)
Description

Hello,

I am trying to get PDF print work with wkhtmltopdf on Windows/IIS.
I have downloaded windows version of wkhtmltopdf and copied it in print/lib directory.

First problem, the program is not detected during setup by print_pdf. This can be fixed in file print_pdf.admin.inc, line 255. Replace '^wkhtmltopdf$' with '^wkhtmltopdf*' (* instead of $). A cleaner patch would detect OS.

Second problem, the program file is not detected when printing. This is because program file name contains a ".exe" extension. Line 88 in file print_pdf.pages.inc should be changed in

  elseif (substr(basename($print_pdf_pdf_tool), 0, 11) == 'wkhtmltopdf') {

Now the pdf converter is detected in setup and when converting. But it does not work.
I have fixed the bug described here : http://drupal.org/node/519320 but it still does not work.

It seems that the stream_get_contents returns an empty stream.

    $pdf = stream_get_contents($pipes[1]);

If I change the command line to redirect output to a file, wkhtmltopdf works OK and I get a valid PDF file.
The program output ($pipes[2]) is OK and says output is complete.

Any idea ?

Thank you,
Frederic

#1

jcnventura - July 17, 2009 - 12:22

From your description, it seems that, in Windows, wkhtmltopdf isn't able to provide any contents before that blocking call returns..

I have no ideia why and I don't use Windows for Drupal personally, so I can't try to reproduce your problem. Maybe someone else will be able to help you.

João

#2

flebas - July 17, 2009 - 15:42

I have done other tests. This is a bug in the Windows version of wkhtmltopdf, that does not output anything on stdout.

I have written a small workaround : PDF output is created in a temporary file $pdf_output_file, then I replace

$pdf = stream_get_contents($pipes[1]);

with

$pdf = file_get_contents($pdf_output_file);
unlink($pdf_output_file);

Not very elegant, but it works.

Thank you for help and software.

Frederic

#3

jcnventura - September 4, 2009 - 12:12
Status:active» postponed (maintainer needs more info)

Can you provide the complete code for this functionality?

#4

flebas - September 18, 2009 - 22:48

Sorry for the delay.

All changes are in _print_pdf_wkhtmltopdf function.

Regards,
Frederic

AttachmentSize
print_pdf.pages_.inc_.txt 18.37 KB

#5

jcnventura - October 3, 2009 - 16:36
Status:postponed (maintainer needs more info)» needs review

It seems your changes were the ones in the attached patch.. However, you were using version 1.7 of the module.. I need you to apply this patch to 1.8 and test it to see if everything's working, as I don't use Drupal on Windows.

AttachmentSize
print_wkhtmltopdf_windows.patch 1.99 KB

#6

jcnventura - October 13, 2009 - 22:02
Status:needs review» fixed

Hi,

I didn't get any answer, so I decided to make these changes and commit them to CVS, hoping that someone will test them. The changes only affect Windows users, so it should be safe for the rest of us.

João

#7

ghede - October 22, 2009 - 06:16

I updated to the latest (6.x-1.10) and thought I'd give it a try. It opens a duplicate browser window with a duplicate copy of the entire site - rather than just the content. Looking in windows/temp I see an html file of just the content - what should be the PDF. Some searching brings this up - http://code.google.com/p/wkhtmltopdf/issues/detail?id=75 - which I assume you already know from the above thread.

I'm no coder, just a user, but willing to play around and test if you like.

Best Regards,
Jim

#8

jcnventura - October 22, 2009 - 10:39
Status:fixed» postponed (maintainer needs more info)

Hi,

If you're willing to help, I would like you to add the following lines to the 'print_pdf.pages.inc' file just below

<?php
$cmd
= realpath($print_pdf_pd .....
?>

Add the lines

<?php
  var_dump
($cmd);
  exit;
?>

Then try to generate a PDF. The browser will display the content of the $cmd variable.

Copy-paste that command and try to run in the the Command Prompt of your server.. Report here whatever is the result of that command.

João

#9

ghede - October 23, 2009 - 04:55

Just for clarification, because I don't think I got what you wanted.

$pdf_output = (stristr(PHP_OS, 'Win')) ? tempnam(file_directory_temp(), 'pdf') : '-';
$cmd = realpath($print_pdf_pdf_tool) ." --page-size $print_pdf_paper_size --orientation $print_pdf_page_orientation --dpi $dpi $print_pdf_wkhtmltopdf_options - $pdf_output";

var_dump($cmd);
exit;

$process = proc_open($cmd, $descriptor, $pipes, NULL, isset($xvfb_binary) ? array('DISPLAY' => ':'. $xdisplay) : NULL);

Here is the output in the browser:

string(211) "C:\www ... ... ... sites\all\modules\print\lib\wkhtmltopdf.exe --page-size letter --orientation portrait --dpi 96 --footer-font-size 7 --footer-right '[page]' - C:\WINDOWS\Temp\pdf27B.tmp"

Jim

#10

jcnventura - October 23, 2009 - 09:21

It's more or less what I wanted..

I didn't remember that it was using standard input. You should now save the HTML output of the printer-friendly version to a file and then execute the following:

type printer-friendly_version.html | C:\www ... ... ... sites\all\modules\print\lib\wkhtmltopdf.exe --page-size letter --orientation portrait --dpi 96 --footer-font-size 7 --footer-right '[page]' - C:\WINDOWS\Temp\pdf27B.tmp

It should generate the PDF version of that page in that temporary file. Execute it in the server so that the process is as close to having it executed by the Web Server as possible.

João

#11

jcnventura - October 23, 2009 - 09:21

#12

ghede - October 26, 2009 - 05:31

Sorry for the late reply. I had to unexpectedly go out for the weekend and apparently while I was out, the video card on the server blew a cap and took the server down. Threw in a temporary card for now.

Anyway, I think you confused me when you said to save the HTML output as their is none when the dump($cmd) is added, so I did this two ways - hope one is right.

Try 1:

I keep this

var_dump($cmd);
exit;

in print_pdf.pages.inc.

I've done this a few times so the file name is slightly different.

I attempt to print a pdf page. It creates the 'pdf...tmp' file in C:\windows\temp\. The file size is 0KB.

I execute this command: type printer-friendly_version.html | C:\www ... ... ... \sites\all\modules\print\lib\wkhtmltopdf.exe --page-size letter --orientation portrait --dpi 96 --footer-font-size 7 --footer-right '[page]' - C:\windows\temp\pdf23.tmp

It comes back with "The system cannot find the file specified", however it re-creates pdf23.tmp in the above \temp directory and now the file size is 6KB.

I rename the file to pdf23.pdf and view it. It's a blank page with the exception of '1' in the bottom right corner.

Try 2:

I remove this

var_dump($cmd);
exit;

from print_pdf.pages.inc.

I attempt to print a pdf page. It creates 'wktemp{blah blah blah}.html' in C:\windows\temp\. I rename it to 'wktemp.html'. I check it out in the browser and it looks great.

I execute this command: type printer-friendly_version.html | C:\www ... ... ... \sites\all\modules\print\lib\wkhtmltopdf.exe --page-size letter --orientation portrait --dpi 96 --footer-font-size 7 --footer-right '[page]' - C:\windows\temp\wktemp.html

It comes back with "The system cannot find the file specified", however it apparently re-creates wktemp.html as the file is now garbage when looked at in the browser.

I've zipped and attached the files so you can see them if you want.

AttachmentSize
wktemp.zip 14.9 KB

#13

jcnventura - October 27, 2009 - 11:28

You're really confused and confusing me..

The key here is the type printer-friendly_version.html at the beginning of the command. That file (printer-friendly_version.html) is the input to the entire process. Since you haven't saved your HTML output with that filename, of course the output of the process is trash, as there was no input in the first place.

The wktemp_before.html file you provided is an excellent file for this test, as it is the output of an intermediate step in the print_pdf module. You should be able to use the following line (modified at the start to use the file you provided and at the end to create a file with the pdf extension).

type wktemp_before.html | C:\www ... ... ... sites\all\modules\print\lib\wkhtmltopdf.exe --page-size letter --orientation portrait --dpi 96 --footer-font-size 7 --footer-right '[page]' - C:\WINDOWS\Temp\output.pdf

After you execute this command, the generated PDF should be located in C:\WINDOWS\Temp\output.pdf.

#14

ghede - October 28, 2009 - 05:50

Ahhhhh, sorry for being so daft. I guess I need drunken monkey directions :)

Ok, I got it to work now that I understand the command better. However, it does not generate a PDF file named output.pdf in C:\WINDOWS\Temp. It opens up the file (wktemp_before.html) in the browser...

So, I looked at the usage in the help for wkhtmltopdf.exe and I changed the command to this:

C:\WINDOWS\Temp>C:\www\ ... ... ... ... \sites\all\modules\print\lib\wkhtmltopdf.exe --page-size letter --orientation portrait --dpi 96 --footer-font-size 7 --footer-right '[page]' C:\windows\temp\wktemp_before.html C:\windows\temp\output.pdf

and it created the file.

However, the file is blank except for the page number in the bottom right corner.

#15

jcnventura - October 28, 2009 - 12:37

I've tested this and there seems to be a conflict in the setting to send the Web page version directly to the printer and generating the PDF via wkhtmltopdf (as the onload=window.print() is REALLY executed by wkhtmltopdf).

Can you disable the option to send directly to the printer in the Web page version settings and try again to generate the PDF? Please remove all the modifications you did to the module before.

João

#16

ghede - October 29, 2009 - 06:04

Ok, I played around a bit tonight. Here's what I've found:

I discovered that if I run wkhtmltopdf from anywhere in the web directory, it gives me the blank pages. If I run it like above, outside the web, it works.

So until I can get it working in the web directory, I can't really answer your question - "disable the option to send directly to the printer in the Web page version settings".

Testing in C:\windows\temp works. I got it working by using the -n switch. This disables javascript, supressing the print function and creating the pdf.

C:\WINDOWS\Temp>wkhtmltopdf wktempbefore.html test.pdf
Failed loading page

C:\WINDOWS\Temp>wkhtmltopdf -n wktempbefore.html test.pdf
Done

And I successfully created other pages saved from the web and created without the -n switch. So it works, but not from my web directory.

Jim

#17

evilive - October 29, 2009 - 09:12

print_pdf.pages.inc; line:315;

$pdf = file_get_contents($pdf_outputg);

#18

jcnventura - October 29, 2009 - 10:00
Status:postponed (maintainer needs more info)» active

@evilive: thanks for pointing that typo/bug out.. As I said, I can't test windows.. Thanks for doing it for me.

#19

jcnventura - November 1, 2009 - 18:25
Status:active» postponed (maintainer needs more info)

I've just committed to CVS a fix for the typo reported in #18.

#20

ghede - November 8, 2009 - 20:45

Ok, I got it working from the command line in the web directory. Just had to add it to the cgi-bin and place the cgi-bin directory under the lib directory. The module also see's it here and I can select wkhtmltopdf to be used.

I also fixed the typo in #17. Still no luck. It continues to open a new instance of the complete web page. I see someone else is having the same problem - http://code.google.com/p/wkhtmltopdf/issues/detail?id=109

So to answer your question in #15, it had no effect, same - it continues to open a new instance of the complete web page.

Something I've noticed:
I see in the address bar of the browser it initially shows http://www....com/printpdf/content/Car-Key-Memory and then is replaced by the same address but without the 'printpdf' in the address - as if it's being removed. Selecting dompdf as the render-er and the pdf page is addressed correctly.

I do have the modules 'global redirect' and 'pathauto' installed. I can try disabling them if you think this is anything.

Jim

#21

jcnventura - November 9, 2009 - 11:31

Have you disabled the 'send directly to printer'?

João

#22

ghede - November 10, 2009 - 06:12

Yes, it had no effect - it continues to open a new instance of the complete web page.

Jim

#23

ghede - November 21, 2009 - 23:02

This thread was kinda left hanging and I wanted to tie up my end of it. I solved this issue using this thread #631150: Print to PDF appears to outrun wkhtmltopdf on Windows with Apache and PDF doesn't download

 
 

Drupal is a registered trademark of Dries Buytaert.