Создать PDF из типов контента Plone - PullRequest
3 голосов
/ 27 сентября 2011

Мне нужно создавать PDF-файлы из типов контента (созданных с ловкостью, если это имеет значение), чтобы пользователь создал новый документ, и после заполнения формы PDF-файл был создан и готов к загрузке.Таким образом, в основном после создания / изменения документа PDF должен быть создан и сохранен в ZODB (на самом деле я использую большие двоичные объекты), чтобы я мог связать представление с «Скачать как PDF».

Я видел PDFNode но, похоже, это не то, что я ищу.Также есть Produce & Publish , но это веб-сервис (?), И компания, для которой я собираюсь разработать это, не хочет (для конфиденциальности) отправлять данные за пределы своих центров обработки данных.

Есть идеи?

Ответы [ 4 ]

4 голосов
/ 27 сентября 2011

Кажется, вы ищете это:

3 голосов
/ 27 сентября 2011

Я на самом деле много делаю в моем проекте. Я использовал Products.SmartPrintNG и fop для него, хотя и не делал этого стандартным способом, который использует продукт (я думаю, что он использует javascript для инициации преобразования .. странно)

Пара вещей:

  • Мне пришлось санировать вывод, потому что fop довольно обидчивый
  • используется lxml
  • шахта использует архетипы

В любом случае, мой обработчик событий для создания PDF выглядит примерно так:

from Products.SmartPrintNG.browser import SmartPrintView
from lxml.cssselect import CSSSelector
from lxml.html import fromstring, tostring
import re

san_re = re.compile('(?P<width>width\=("|\')\d{1,5}(px|%|in|cm|mm|em|ex|pt|pc)?("|\'))')

class Options(object):

    def __init__(self, __dict):
        self.__dict = __dict

    def __getattr__(self, attr):
        if self.__dict.has_key(attr):
            return self.__dict[attr]
        raise AttributeError(attr)

def sanitize_xml(xml):
    selector = CSSSelector('table,td,tr')
    elems = selector(xml)
    for el in elems:
        if el.attrib.has_key('width'):
            width = el.attrib['width']
            style = el.attrib.get('style', '').strip()
            if style and not style.endswith(';'):
                style += ';'
            style += 'width:%s;' % width
            del el.attrib['width'] 
            el.attrib['style'] = style

    return xml

def save_pdf(obj, event):
    smartprint = SmartPrintView(obj, obj.REQUEST)
    html = obj.restrictedTraverse('view')()
    xml = fromstring(html)
    selector = CSSSelector('div#content')
    xml = selector(xml)
    html = tostring(sanitize_xml(xml[0]))
    res = smartprint.convert(
        html=html,
        format='pdf2',
        options=Options({'stylesheet': 'pdf_output_stylesheet', 'template': 'StandardTemplate'})
    )

    field = obj.getField('generatedPDF')
    field.set(obj, res, mimetype='application/pdf', _initializing_=True)
    field.setFilename(obj, obj.getId() + '.pdf')
2 голосов
/ 28 сентября 2011

Produce and Publish Lite - это автономный код с открытым исходным кодом, преемник SmartPrintNG.http://pypi.python.org/pypi/zopyx.smartprintng.lite/

0 голосов
/ 29 сентября 2011

используйте z3c.rml, очень хорошо работает для создания pdf из шаблона rml вместо преобразования из html, что может быть сложно.

...