Кто-нибудь мог использовать 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.