2010-08-28 4 views
0

Я использую Reportlab для создания PDF-файлов. Я создаю два PDF-файла, которые я хочу объединить после создания. Reportlab обеспечивает способ сохранения pycanvas (source) (который в основном является моим файлом PDF в памяти) в виде файла python и вызовом метода doIt (filename) в этом файле python, воссоздает файл pdf. Это здорово, так как вы можете объединить два PDF-файла на основе исходного кода и создать одно слияние pdf.экземпляр класса python из класса, доступного как строка, только в памяти!

Это делается так:

from reportlab.pdfgen import canvas, pycanvas 
#create your canvas 
p = pycanvas.Canvas(buffer,pagesize=PAGESIZE) 
#...instantiate your pdf... 

# after that, close the PDF object cleanly. 
p.showPage() 
p.save() 

#now create the string equivalent of your canvas 
source_code_equiv = str(p) 
source_code_equiv2 = str(p) 

#merge the two files on str. basis 
#not shown how it is exactly done, to make it more easy to read the source 
#actually one just have to take the middle part of source_code_equiv2 and add it into source_code_equiv 
final_pdf = source_code_equiv_part1 + source_code_equiv2_center_part + source_code_equiv_part2 

#write the source-code equivalent of the pdf 
open("n2.py","w").write(final_pdf) 
from myproject import n2 
p = n2.doIt(buffer) 

# Get the value of the StringIO buffer and write it to the response. 
pdf = buffer.getvalue() 
buffer.close() 
response.write(pdf) 
return response 

Это прекрасно работает, но я хочу, чтобы пропустить шаг, который я сохранить n2.py на диск. Таким образом, я ищу способ создания экземпляра final_pdf соответствующего класса python и использования его непосредственно в источнике. Это возможно?

Он должен работать как-то так ..

n2 = instantiate_python_class_from_source(final_pdf) 
p = n2.doIt(buffer) 

Причина этого заключается в том, что в основном есть на самом деле не нужно, чтобы сохранить источник на диск, а во-вторых, что она абсолютно не поточно сохранить. Я могу назвать созданный файл во время выполнения, но тогда я не знаю, что импортировать !? Если нет способа предотвратить сохранение файла, существует ли способ определить импорт на основе имени файла, который определяется во время выполнения !?

Можно спросить, почему я не создаю один PDF заранее, но это невозможно, поскольку они происходят из разных приложений.

+0

ли код вы предоставили действительно минимально необходимую для объясните вопрос? Это довольно долго. – allyourcode

+0

должно быть лучше сейчас .. –

ответ

1

Это похоже на очень долгий путь к тому, что вы хотите. Не имеет ли ReportLab класс Canvas, из которого вы можете извлечь документ PDF? Я не понимаю, почему здесь должен быть задействован исходный код Python.

Но если по какой-то причине необходимо, то вы можете использовать StringIO «писать» источник в строку, а затем EXEC для его выполнения:

from cStringIO import StringIO 

source_code = StringIO() 
source_code.write(final_pdf) 
exec(source_code) 
p = doIt(buffer) 
+0

hmm .. Просто вызов doIt (buffer) не будет работать, так как doIt() - это метод сериализованных pycanvas. –

+0

Я думаю, нам нужно будет увидеть образец этого сгенерированного источника, чтобы узнать правильный синтаксис. Если вы можете записать его на n2.py, затем импортируйте n2, затем вызовите n2.doIt(), тогда мой код также должен работать. –

+0

Я бы трижды проверил, что вам нужно вообще сгенерировать код Python. Это определенно кажется, что есть более простой способ сделать это. –

0

Хорошо, я думаю, вы могли бы использовать модуль кода, который обеспечивает интерактивный режим стандартного интерпретатора. Следующее выполнило бы функцию doIt.

import code 
import string 
coded_data = """ 
def doIt(): 
    print "XXXXX" 
""" 
script = coded_data + "\ndoIt()\n" 
co = code.compile_command(script, "<stdin>", "exec") 
if co: 
    exec co 

Дайте мне знать, если это поможет.

+0

Спасибо, но я еще не уверен, помогает ли он :-) Мне понадобится возвращаемое значение метода call doIt (buffer), назначенного p, как я делаю с этим утверждением: p = n2.doIt (буфер) .. это возможно? –