IIS 上的 django-wkhtmltopdf:[WinError 6] 句柄无效
django-wkhtmltopdf on IIS: [WinError 6] The handle is invalid
这是我的第一个问题,所以请原谅我,如果我忘了说什么或者有什么问题:)
我在 IIS(10)-Windows 服务器上设置了一个 python(3.5.3)-django(2.1.5) -project。一切都很好。
问题
只有 wkhtmltopdf(0.12.5) 有一个奇怪的行为。
当我 运行 它在本地主机上时,命令提示符给我
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
而且我可以在我的下载文件夹中按预期找到生成的 .pdf 文件。
当我将 ALLOWED_HOSTS
更改为服务器的 IP 并调用 url 生成 pdf 时,它说有一个
OSError at /pdf/
[WinError 6] The handle is invalid
追溯:
File
"C:\my_project\myenv\lib\site-packages\django\core\handlers\exception.py"
in inner
34. response = get_response(request)
File
"C:\my_project\myenv\lib\site-packages\django\core\handlers\base.py"
in _get_response
156. response = self.process_exception_by_middleware(e, request)
File
"C:\my_project\myenv\lib\site-packages\django\core\handlers\base.py"
in _get_response
154. response = response.render()
File
"C:\my_project\myenv\lib\site-packages\django\template\response.py"
in render
106. self.content = self.rendered_content
File
"C:\my_project\myenv\lib\site-packages\wkhtmltopdf\views.py"
in rendered_content
80. cover_template=self.resolve_template(self.cover_template)
File
"C:\my_project\myenv\lib\site-packages\wkhtmltopdf\utils.py"
in render_pdf_from_template
237. cover_filename=cover.filename if cover else None)
File
"C:\my_project\myenv\lib\site-packages\wkhtmltopdf\utils.py"
in convert_to_pdf
166. return wkhtmltopdf(pages=pages, **cmd_options)
File
"C:\my_project\myenv\lib\site-packages\wkhtmltopdf\utils.py"
in wkhtmltopdf
147. return check_output(ck_args, **ck_kwargs)
File "C:\Program Files\Python35\lib\subprocess.py" in check_output
316. **kwargs).stdout
File "C:\Program Files\Python35\lib\subprocess.py" in run
383. with Popen(*popenargs, **kwargs) as process:
File "C:\Program Files\Python35\lib\subprocess.py" in init
640. errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "C:\Program Files\Python35\lib\subprocess.py" in _get_handles
884. errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE)
Exception Type: OSError at /pdf/
Exception Value: [WinError 6] Das
Handle ist ungültig
我可以在 C:\Users\myapplicationpool\AppData\Local\Temp
-文件夹中看到 wkhtmltopdf 正在生成一个名为 wkhtmltopdfgn1s7k5r.html
的 .html-文件,但不知何故进度卡住了。
如前所述 here and 其他人也有同样的问题。但是改变
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
process = Popen(stdout=PIPE, *popenargs, **kwargs)
到
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
kwargs.pop('stderr', None)
process = Popen(stdout=PIPE, stderr=PIPE, stdin=PIPE, *popenargs, **kwargs)
没有效果。我认为此解决方案仅适用于 Python 2.7 的 subprocess.py 文件,我正在使用 Python 3+ 并且此文件的功能已更改。
我为 IUSR
和 IIS_USRS
用户授予 wkhtmltopdf 文件夹的完全权限,其中 bin 文件夹和 wkhtmltopdf.exe 位于我读到的内容也可以提供帮助,但它没有。
问题
有没有人知道我可以尝试什么并帮助我?
这个问题真的出在 wkhtmltopdf 和 python 的子进程中,还是我宁愿 change/add IIS 中 FastCgiModule 的 djangohandler 的处理程序?我该怎么做?
为什么当我 运行 它作为 localhost 在本地服务器上运行时没有任何问题,但当我通过服务器的 IP 调用页面时却没有? -- 如前所述:其他一切正常。
设置
我将 wkhtmltopdf 添加到 INSTALLED_APPS
并设置如下:
settings.py
WKHTMLTOPDF_CMD = 'C:/wkhtmltopdf/bin/wkhtmltopdf'
(据我所知,在 'Program Files'
中安装时,路径中经常出现空格问题。)
urls.py
path('pdf/', views.MyPDFView.as_view(), name='pdfview'),
views.py
from wkhtmltopdf.views import PDFTemplateResponse
class MyPDFView(View):
template_name='mypdfview.html'
def get(self, request):
response = PDFTemplateResponse(request=self.request,
template=self.template_name,
filename='hello' + '.pdf',
context=self.context,
show_content_in_browser=False,
cmd_options={
'margin-top': 50,
},
)
return response
mypdfview.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Hello World</title>
</head>
<body>
<h1>Some headline here.</h1>
</body>
</html>
编辑 1:
不知何故我的问候语消失了 - 添加它......
编辑 2:
好像不能说:"Hi everyone"!?
要执行与 python 2.7 相同的解决方法,您需要编辑 wkhtmltopdf/utils.py 文件,方法 wkhtmltopdf()
:
from .subprocess import check_output, PIPE
...
def wkhtmltopdf(pages, output=None, **kwargs):
...
except (AttributeError, IOError):
# can't call fileno() on mod_wsgi stderr object
pass
# add this:
if not ck_kwargs.get('stderr'):
ck_kwargs['stderr'] = PIPE
return check_output(ck_args, **ck_kwargs)
这是我的第一个问题,所以请原谅我,如果我忘了说什么或者有什么问题:)
我在 IIS(10)-Windows 服务器上设置了一个 python(3.5.3)-django(2.1.5) -project。一切都很好。
问题
只有 wkhtmltopdf(0.12.5) 有一个奇怪的行为。
当我 运行 它在本地主机上时,命令提示符给我
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
而且我可以在我的下载文件夹中按预期找到生成的 .pdf 文件。
当我将 ALLOWED_HOSTS
更改为服务器的 IP 并调用 url 生成 pdf 时,它说有一个
OSError at /pdf/
[WinError 6] The handle is invalid
追溯:
File "C:\my_project\myenv\lib\site-packages\django\core\handlers\exception.py" in inner 34. response = get_response(request)
File "C:\my_project\myenv\lib\site-packages\django\core\handlers\base.py" in _get_response 156. response = self.process_exception_by_middleware(e, request)
File "C:\my_project\myenv\lib\site-packages\django\core\handlers\base.py" in _get_response 154. response = response.render()
File "C:\my_project\myenv\lib\site-packages\django\template\response.py" in render 106. self.content = self.rendered_content
File "C:\my_project\myenv\lib\site-packages\wkhtmltopdf\views.py" in rendered_content 80. cover_template=self.resolve_template(self.cover_template)
File "C:\my_project\myenv\lib\site-packages\wkhtmltopdf\utils.py" in render_pdf_from_template 237. cover_filename=cover.filename if cover else None)
File "C:\my_project\myenv\lib\site-packages\wkhtmltopdf\utils.py" in convert_to_pdf 166. return wkhtmltopdf(pages=pages, **cmd_options)
File "C:\my_project\myenv\lib\site-packages\wkhtmltopdf\utils.py" in wkhtmltopdf 147. return check_output(ck_args, **ck_kwargs)
File "C:\Program Files\Python35\lib\subprocess.py" in check_output 316. **kwargs).stdout
File "C:\Program Files\Python35\lib\subprocess.py" in run 383. with Popen(*popenargs, **kwargs) as process:
File "C:\Program Files\Python35\lib\subprocess.py" in init 640. errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "C:\Program Files\Python35\lib\subprocess.py" in _get_handles 884. errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE)
Exception Type: OSError at /pdf/ Exception Value: [WinError 6] Das Handle ist ungültig
我可以在 C:\Users\myapplicationpool\AppData\Local\Temp
-文件夹中看到 wkhtmltopdf 正在生成一个名为 wkhtmltopdfgn1s7k5r.html
的 .html-文件,但不知何故进度卡住了。
如前所述 here and
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
process = Popen(stdout=PIPE, *popenargs, **kwargs)
到
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
kwargs.pop('stderr', None)
process = Popen(stdout=PIPE, stderr=PIPE, stdin=PIPE, *popenargs, **kwargs)
没有效果。我认为此解决方案仅适用于 Python 2.7 的 subprocess.py 文件,我正在使用 Python 3+ 并且此文件的功能已更改。
我为 IUSR
和 IIS_USRS
用户授予 wkhtmltopdf 文件夹的完全权限,其中 bin 文件夹和 wkhtmltopdf.exe 位于我读到的内容也可以提供帮助,但它没有。
问题
有没有人知道我可以尝试什么并帮助我?
这个问题真的出在 wkhtmltopdf 和 python 的子进程中,还是我宁愿 change/add IIS 中 FastCgiModule 的 djangohandler 的处理程序?我该怎么做?
为什么当我 运行 它作为 localhost 在本地服务器上运行时没有任何问题,但当我通过服务器的 IP 调用页面时却没有? -- 如前所述:其他一切正常。
设置
我将 wkhtmltopdf 添加到 INSTALLED_APPS
并设置如下:
settings.py
WKHTMLTOPDF_CMD = 'C:/wkhtmltopdf/bin/wkhtmltopdf'
(据我所知,在 'Program Files'
中安装时,路径中经常出现空格问题。)
urls.py
path('pdf/', views.MyPDFView.as_view(), name='pdfview'),
views.py
from wkhtmltopdf.views import PDFTemplateResponse
class MyPDFView(View):
template_name='mypdfview.html'
def get(self, request):
response = PDFTemplateResponse(request=self.request,
template=self.template_name,
filename='hello' + '.pdf',
context=self.context,
show_content_in_browser=False,
cmd_options={
'margin-top': 50,
},
)
return response
mypdfview.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Hello World</title>
</head>
<body>
<h1>Some headline here.</h1>
</body>
</html>
编辑 1: 不知何故我的问候语消失了 - 添加它...... 编辑 2: 好像不能说:"Hi everyone"!?
要执行与 python 2.7 相同的解决方法,您需要编辑 wkhtmltopdf/utils.py 文件,方法 wkhtmltopdf()
:
from .subprocess import check_output, PIPE
...
def wkhtmltopdf(pages, output=None, **kwargs):
...
except (AttributeError, IOError):
# can't call fileno() on mod_wsgi stderr object
pass
# add this:
if not ck_kwargs.get('stderr'):
ck_kwargs['stderr'] = PIPE
return check_output(ck_args, **ck_kwargs)