Кто-нибудь мог использовать poppler new_from_data в python?

Используя Python3 и Poppler, я могу без проблем загружать файлы с new_from_file, но new_from_data проблематичен. Вот код, который, очевидно, является простым тестом, потому что не имеет смысла читать из файла и затем использовать new_from_data, так как new_from_file работает отлично, но я не смог опубликовать здесь полный код, генерирующий файл PDF.

from gi.repository import Poppler, Gtk

def draw(widget, cr):
        # set background.
        cr.set_source_rgb(0.7, 0.6, 0.5)
        cr.paint()

        # set page background
        cr.set_source_rgb(1, 1, 1)
        cr.rectangle(0,0,800,400)

        cr.fill()
        page.render(cr)

filepath = "d:/Mes Documents/A5.pdf" 
f11 = open(filepath, "r", encoding = "cp850")
data1 = f11.read()
f11.close()

document = Poppler.Document.new_from_data(data1, len(data1),  None)
page = document.get_page(0)
print (document.get_n_pages())


window = Gtk.Window(title="Hello World")
window.connect("delete-event", Gtk.main_quit)
window.connect("draw", draw)
window.set_app_paintable(True)

window.show_all()
Gtk.main()

Могут возникнуть четыре разные ситуации:

  • С очень простым pdf (пример "Hello world" в Pdf Reference 13) это работает.
  • В обычном файле ошибки не может быть, но get_n_pages возвращает 0, а get_page(0) возвращает None
  • Или я могу получить ошибку: GLib.Error: poppler-quark: PDF-документ поврежден (4)
  • Или программа вылетает

Интересно, может быть проблема в параметре кодирования, но я попробовал все, о чем думал, безрезультатно. Я попытался с "rb", а затем преобразовать массив байтов в строку с:

data1 = "".join(map(data1))

Безрезультатно.

Поиск в Google никогда не возвращал рабочий пример

1 ответ

Решение

Я столкнулся с той же проблемой, решил ее с помощью Gio.MemoryInputStream. Не очень элегантно, но это работает...

from gi.repository import Poppler, Gtk, Gio

def draw(widget, cr):
        # set background.
        cr.set_source_rgb(0.7, 0.6, 0.5)
        cr.paint()

        # set page background
        cr.set_source_rgb(1, 1, 1)
        cr.rectangle(0,0,800,400)

        cr.fill()
        page.render(cr)

filepath = "d:/Mes Documents/A5.pdf" 
with open(filepath, "rb") as f11:
    input_stream = Gio.MemoryInputStream.new_from_data(f11.read())
    # Take care that you need to call .close() on the Gio.MemoryInputStream once you're done with your pdf document.

document = Poppler.Document.new_from_stream(input_stream, -1, None, None)
page = document.get_page(0)
print (document.get_n_pages())


window = Gtk.Window(title="Hello World")
window.connect("delete-event", Gtk.main_quit)
window.connect("draw", draw)
window.set_app_paintable(True)

window.show_all()
Gtk.main()

Работает, если вы читаете файл как двоичный "rb"и без кодирования. Мне также нужно было удалить длину данных, чтобы исправитьTypeError: Poppler.Document.new_from_data() takes exactly 2 arguments (3 given) (в версиях poppler мог быть другим).

#!/bin/python3
from gi.repository import Poppler, Gtk

def draw(widget, cr):
        # set background.
        cr.set_source_rgb(0.7, 0.6, 0.5)
        cr.paint()

        # set page background
        cr.set_source_rgb(1, 1, 1)
        cr.rectangle(0,0,800,400)

        cr.fill()
        page.render(cr)

filepath = "/home/da/test.pdf"
f11 = open(filepath, "rb")
data1 = f11.read()
f11.close()

document = Poppler.Document.new_from_data(data1, None)
page = document.get_page(0)
print (document.get_n_pages())


window = Gtk.Window(title="Hello World")
window.connect("delete-event", Gtk.main_quit)
window.connect("draw", draw)
window.set_app_paintable(True)

window.show_all()
Gtk.main()

Протестировано с poppler 0.84.0 и Python 3.8.5 в Fedora Linux.

Другие вопросы по тегам