根据给定here的示例,我正在尝试使用Django应用程序从用LaTeX编写的模板生成PDF。请注意,我还没有进入使用数据库中的值填充LaTeX模板文件的阶段。它目前有“硬编码”内容,我只是想让PDF生成工作先发挥作用。
from django.shortcuts import render
from django.http import HttpResponse
from django.template import Context
from django.template.loader import get_template
from subprocess import Popen, PIPE
import tempfile
def pdf(request):
context = Context({})
template = get_template('cv.tex')
rendered_tpl = template.render(context).encode('utf-8')
with tempfile.TemporaryDirectory() as tempdir:
# Create subprocess, supress output with PIPE and
# run latex twice to generate the TOC properly.
# Finally read the generated pdf.
for i in range(2):
process = Popen(
['pdflatex', '-output-directory', tempdir],
stdin=PIPE,
stdout=PIPE,
)
process.communicate(rendered_tpl)
with open(os.path.join(tempdir, 'texput.pdf'), 'rb') as f:
pdf = f.read()
r = HttpResponse(content_type='application/pdf')
r.write(pdf)
return r
但是当我转到我指向视图的URL时,我收到以下错误。
Internal Server Error: /cv.pdf
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\LThorburn\Documents\Dropbox\Code\lt.co\cv\views.py", line 45, in pdf
with open(os.path.join(tempdir, 'texput.pdf'), 'rb') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\LTHORB~1\\AppData\\Local\\Temp\\tmpik2iw24w\\texput.
pdf'
我对处理临时文件不是很熟悉。我需要做什么?
为了回应@ stovfl的建议,我将with tempfile.TemporaryDirectory() as tempdir:
替换为with tempfile.TemporaryDirectory(dir='.') as tempdir:
。这导致了以下新错误:
C:\Users\LThorburn\Documents\Dropbox\Code\lt.co\cv\views.py:33: RemovedInDjango110Warning: render() must be called with
a dict, not a Context.
rendered_tpl = template.render(context).encode('utf-8')
pdflatex: Unknown archive file size.
pdflatex: Data: resume
pdflatex: Unknown archive file size.
pdflatex: Data: resume
[FAIL] File .\tmppml24lmd\texput.pdf not found
Internal Server Error: /cv.pdf
Traceback (most recent call last):
File "C:\Users\LThorburn\Documents\Dropbox\Code\lt.co\cv\views.py", line 51, in pdf
with open(os.path.join(tempdir, 'texput.pdf'), 'rb') as f:
FileNotFoundError: [Errno 2] No such file or directory: '.\\tmppml24lmd\\texput.pdf'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\LThorburn\Documents\Dropbox\Code\lt.co\cv\views.py", line 52, in pdf
pdf = f.read()
File "C:\Python34\lib\tempfile.py", line 685, in __exit__
self.cleanup()
File "C:\Python34\lib\tempfile.py", line 689, in cleanup
_shutil.rmtree(self.name)
File "C:\Python34\lib\shutil.py", line 478, in rmtree
return _rmtree_unsafe(path, onerror)
File "C:\Python34\lib\shutil.py", line 377, in _rmtree_unsafe
onerror(os.rmdir, path, sys.exc_info())
File "C:\Python34\lib\shutil.py", line 375, in _rmtree_unsafe
os.rmdir(path)
OSError: [WinError 145] The directory is not empty: '.\\tmppml24lmd'
[08/Mar/2017 22:15:50] "GET /cv.pdf HTTP/1.1" 500 96729
答案 0 :(得分:2)
.log
文件时,我不认为问题是由于' Tempfile'因为您的错误处理的是.log
文件而不是像您的代码所示的随机创建的临时目录。
当我运行以下代码时:
with tempfile.TemporaryDirectory() as tempdir:
print(os.path.join(tempdir, 'test.txt'))
with open(os.path.join(tempdir, 'test.txt'),"w") as tmpfile:
tmpfile.write("test.txt")
我得到以下输出:
/var/folders/xj/zz73z72j0bb80kt2x6z8sfq5p7zwwg/T/tmpfhk0qwjf/test.txt
请注意,目录是随机的,而不是文件。
您似乎在访问随机生成的日志文件时遇到问题。
此外,您可能需要考虑对代码进行一些改进:
pdflatex
命令失败做好准备。您假设始终生成输出文件。更详细的追溯将有助于进一步追踪错误。
当错误发生时,您可以尝试打印pdflatex
命令的STDOUT和STDERR:
process.communicate(rendered_tpl)
with open(os.path.join(tempdir, 'texput.pdf'), 'rb') as f:
pdf = f.read()
使用:
out,err = process.communicate(rendered_tpl)
try:
fn = os.path.join(tempdir, 'texput.pdf')
f = open(fn)
pdf = f.read()
f.close()
except FileNotFoundError:
raise FileNotFoundError("Could not find {}.\nSTDOUT from pdflatex:{}.\nSTDERR from pdflatex:{}\n",format(fn,out,err))
好了,现在很清楚,该命令没有生成您正在查找的文件并且给您错误LaTeX Error: File 'res.cls' not found. ... there is probably something wrong with the class file.
您似乎需要下载res
类文件才能使应用程序正常运行。您可以找到更多信息here。
答案 1 :(得分:1)
第三次跟进:
意外结果:
在本地更改后,请更新您问题中的代码。 所以我们可以比较Output,Traceback!
请在exit(1)
块中添加except
,这样我们就不会对folloup错误感到不安:
except os.error:
print('[FAIL] File %s not found\nEXIT(1)' % path2pdf)
exit(1)
请在测试时将循环次数设置为1
for i in range(1):
新的错误!
您是否已双重检查插入dir='.'
是唯一的更改?
C:\用户\ LThorburn \文件\收存箱\代码\ lt.co \ CV \ views.py:33: RemovedInDjango110 警告:必须使用dict调用render(),而不是上下文。
rendered_tpl = template.render(context).encode('utf-8')
您指出的示例使用:
context = Context({ 'content': entry.content, })
你用的是
context = Context({})
不得不深入研究,但由于此警告之前没有显示,
我想你已经改变了其他任何事情。
pdflatex:未知的存档文件大小。 pdflatex:数据:简历
process.communicate(rendered_tpl)
的输出
您是否曾从命令控制台尝试过pdflatex?
是什么赋予了:
C:pdflatex -output-directory - < cv.tex 强> 第二次跟进:
使用指向pdf文件的新Traceback更新问题后,
我们必须验证pdflatex
无法创建pdf文件的原因。
首先,我们检查Process
是否具有写权限。
更改你的身份
with tempfile.TemporaryDirectory() as tempdir:
到
with tempfile.TemporaryDirectory(dir='.') as tempdir:
这会将tempdir从OS位置移动到您的脚本正在运行的当前目录。 请评论,因为它的行为相同。