Hallo zusammen,
Ich suche eine Möglichkeit, PDF-Dateien direkt aus Python heraus zu drucken.
Mein Betriebssystem ist Linux Kubuntu 14.04 LTS.
Was benötige ich dazu, bzw. gibt es dafür schon etwas Fertiges?
Grüße Nobuddy
PDF-Dateien direkt aus Python heraus drucken
- diesch
- User
- Beiträge: 80
- Registriert: Dienstag 14. April 2009, 13:36
- Wohnort: Brandenburg a.d. Havel
- Kontaktdaten:
Sollte mit https://pypi.python.org/pypi/pycups gehen
http://www.florian-diesch.de
Entschuldige bitte, aber das ist ein Zweizeiler. Ich dachte du kannst mit den von mir genannten Begriffen was anfangen. Selbst wenn nicht, wenn du "lp subprocess" in eine Suchmaschine deiner Wahl eingibst, wirst du mit Sicherheit fündig werden. Ansonsten hilft auch ein "man lp" im Terminal weiter und die Dokumentation zum subprocess-Modul findest du in der offiziellen Python-Doku.
@pycups: AFAIK ist das nur zur Verwaltung von Druckern und nicht zum Drucken selbst gedacht.
@pycups: AFAIK ist das nur zur Verwaltung von Druckern und nicht zum Drucken selbst gedacht.
@EmaNymton: Es gibt auf `cups.Connection`-Exemplaren eine `printFile()`-Methode wo man Druckername, lokalen Dateinamen, und Optionen angeben kann. Sieht also so aus als könnte man auch damit drucken.
Um BlackJack zu zitieren: "Es gibt auf `cups.Connection`-Exemplaren eine `printFile()`-Methode wo man Druckername, lokalen Dateinamen, und Optionen angeben kann.".Nobuddy hat geschrieben:Vielleicht kann mir das Jemand verraten?
Hallo /me,
habe schon BlackJackś Info gelesen ... und stehe doch auf dem Schlauch. :K
Mittels cupstree.py habe ich Druckernamen und URI, meines LAN-Druckers erhalten.
Wenn ich nicht verkehrt liege, ist die test.py zum Drucken da.
Ich habe diese mal entsprechend editiert und sieht momentan so aus:
Leider habe ich mit den Optionen erhebliche Schwierigkeiten.
Wäre schön, wenn Ihr mir da weiter helfen könntet!
Bin ich mit einem Teil des Codes auf dem richtigen Weg, oder total verkehrt?
Grüße Nobuddy
habe schon BlackJackś Info gelesen ... und stehe doch auf dem Schlauch. :K
Mittels cupstree.py habe ich Druckernamen und URI, meines LAN-Druckers erhalten.
Wenn ich nicht verkehrt liege, ist die test.py zum Drucken da.
Ich habe diese mal entsprechend editiert und sieht momentan so aus:
Code: Alles auswählen
#!/usr/bin/python
import cups
# Simple demonstration of cups module
PRINTER = 'MFC8860DN'
PRINTERNAME = 'MFC8860DN[@localhost]'
URI = 'socket://192.168.178.30:9100'
FILE = '/home/pfad/zu/meiner/pdf_datei/a.pdf'
def callback(prompt):
print ("Password is required for this operation")
password = raw_input(prompt)
return password
def test_cups_module():
cups.setUser("root")
cups.setPasswordCB(callback)
conn = cups.Connection()
printers = list(conn.getPrinters().keys())
pi = [i for i, printer in enumerate(printers)
if printer == PRINTER][0]
if 0:
file(FILE, "w")
conn.getFile(PRINTERNAME, FILE)
conn.putFile(PRINTERNAME, FILE)
print("Getting PPD for %s" % printers[pi])
f = conn.getPPD(printers[pi])
ppd = cups.PPD(f)
ppd.markDefaults()
print (ppd.conflicts())
groups = ppd.optionGroups
for group in groups:
for opt in group.options:
print(list(map(lambda x: x["text"], opt.choices)))
# conn.printFile(PRINTERNAME, FILE, ??optionen??)
test_cups_module ()
Wäre schön, wenn Ihr mir da weiter helfen könntet!
Bin ich mit einem Teil des Codes auf dem richtigen Weg, oder total verkehrt?
Grüße Nobuddy
Nun habe ich es doch noch geschafft, eine PDF-Datei auszudrucken.
Grüße Nobuddy
Code: Alles auswählen
#!/usr/bin/python
import cups
# Simple demonstration of cups module
PRINTER = 'MFC8860DN'
PRINTERNAME = 'MFC8860DN[@localhost]'
URI = 'socket://192.168.178.30:9100'
FILE = '/home/pfad/zu/meiner/pdf_datei/a.pdf'
def callback(prompt):
print ("Password is required for this operation")
password = raw_input(prompt)
return password
def test_cups_module():
cups.setUser("root")
cups.setPasswordCB(callback)
conn = cups.Connection()
printers = list(conn.getPrinters().keys())
pi = [i for i, printer in enumerate(printers)
if printer == PRINTER][0]
if 0:
file(FILE, "w")
conn.getFile(PRINTERNAME, FILE)
conn.putFile(PRINTERNAME, FILE)
print("Getting PPD for %s" % printers[pi])
f = conn.getPPD(printers[pi])
ppd = cups.PPD(f)
ppd.markDefaults()
print (ppd.conflicts())
groups = ppd.optionGroups
title = FILE.split("/")[-1]
conn.printFile(PRINTER, FILE, title=title, options={'copies': '1'})
Natürlich geht es auch kompliziert. Ich mache dies so:
Solange dies nur lokal läuft, ist es für mich gut genug.
Code: Alles auswählen
def print_invoice_pdf(path):
"""Print a given pdf-file. path must be absolute."""
subprocess.call(['lp', path])
- diesch
- User
- Beiträge: 80
- Registriert: Dienstag 14. April 2009, 13:36
- Wohnort: Brandenburg a.d. Havel
- Kontaktdaten:
Als Minimalvariante reicht sowas wieNobuddy hat geschrieben:Nun habe ich es doch noch geschafft, eine PDF-Datei auszudrucken.
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
import cups
PRINTER = 'PDF'
FILE = 'test.pdf'
conn = cups.Connection()
conn.printFile(PRINTER, FILE, title='test', options={})
http://www.florian-diesch.de
- diesch
- User
- Beiträge: 80
- Registriert: Dienstag 14. April 2009, 13:36
- Wohnort: Brandenburg a.d. Havel
- Kontaktdaten:
Da musst du dafür sorgen, dass der Pfad nicht mit einem - anfängt, sonst interpretiert lp das als Option.kbr hat geschrieben:Natürlich geht es auch kompliziert. Ich mache dies so:Solange dies nur lokal läuft, ist es für mich gut genug.Code: Alles auswählen
def print_invoice_pdf(path): """Print a given pdf-file. path must be absolute.""" subprocess.call(['lp', path])
Die Lösung funktioniert nur, wenn der Benutzer kein Passwort zum Drucken benötigt. Und sie ist schlecht erweiterbar, wenn du mehr willst, als nur ein Datei mit festen Optionen zu drucken, z.B. auch eine Drucker-Auswahl anbieten.
http://www.florian-diesch.de
- diesch
- User
- Beiträge: 80
- Registriert: Dienstag 14. April 2009, 13:36
- Wohnort: Brandenburg a.d. Havel
- Kontaktdaten:
Nobuddy hat geschrieben: Wie ist das bei den options, wenn ich ein 5-seitiges Dokument habe, bei dem ich nur Seite 2 bis 3 ausdrucken möchte?
Code: Alles auswählen
options={'page-ranges':'2-3'}
http://www.florian-diesch.de
Hallo diesch,
Danke für Deine Info!
Ich habe einfach mal etwas herum gespielt und die cupstree.py editiert.
Zuerst habe ich eine Klasse erstellt und dann mit ein paar nützlichen Funktionen versehen.
Ich denke, daß sich mit dem Code von cupstree.py noch einiges mehr sich herausholen lässt.
Hier mal mein Änderungs-Code:
Mit der Funktion 'print2document', übergebe ich nur noch das Druckdokument mit Pfad.
Der Standard-Drucker, wird automatisch übergeben.
Bei Zeile 92:bin ich mir nicht sicher, ob dies gebraucht wird und welche Aufgabe aus 'print' resultiert.
Grüße Nobuddy
Danke für Deine Info!
Ich habe einfach mal etwas herum gespielt und die cupstree.py editiert.
Zuerst habe ich eine Klasse erstellt und dann mit ein paar nützlichen Funktionen versehen.
Ich denke, daß sich mit dem Code von cupstree.py noch einiges mehr sich herausholen lässt.
Hier mal mein Änderungs-Code:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x
import cups
class CUPS_Pool(object):
"""
Erstellung von System-Informationen zu CUPS-Drucker.
"""
def __init__(self, host=None, depth=0):
if host:
cups.setServer(host)
else:
host = "localhost"
c = cups.Connection()
printers = c.getPrinters()
classes = c.getClasses()
self.default_printer = c.getDefault()
self.indent = self.do_indent(depth)
self.ident_number = 0
self.conn = cups.Connection()
self.printerpool = list()
self.printersettings = dict()
for name, queue in printers.items():
self.getqueue(name, queue, host, depth, printers, classes)
def do_indent(self, indent):
return " "*indent
def getippqueue(self, dev, queue, depth):
name = dev.rfind('/')
name = dev[name + 1:]
dev = dev[6:]
e = dev.find(':')
if e == -1:
e = dev.find('/')
host = dev[:e]
cups.setServer(host)
try:
c = cups.Connection()
printers = c.getPrinters()
classes = c.getClasses()
except RuntimeError:
# Failed to connect.
return
except cups.IPPError as e:
if e == cups.IPP_OPERATION_NOT_SUPPORTED:
# CUPS-Get-Printers not supported so not a CUPS server.
printers = {}
classes = {}
else:
return
queue = c.getPrinterAttributes(name)
dev = queue['device-uri']
self.getqueue(name, queue, host, depth + 1, printers, classes)
def getqueue(self, name, queue, host, depth, printers, classes):
self.indent = self.do_indent(depth)
if queue['printer-type'] & cups.CUPS_PRINTER_CLASS:
print("%s* Name:\t%s[@%s] (class)" % (self.indent, name, host))
dev = queue['device-uri']
if dev.startswith('ipp:'):
self.getippqueue(dev, queue, depth)
else:
members = classes[name]
depth += 1
self.indent = self.do_indent(depth)
for member in members:
self.getqueue(member, printers[member], host,
depth, printers, classes)
else:
print("%s* Name:\t%s[@%s]" % (self.indent, name, host))
printer_name = name
printer_host = "%s[@%s]" % (name, host)
dev = queue['device-uri']
info = queue['printer-info']
print("%sURI:\t%s" % (self.indent, dev))
printer_uri = dev
print("%sInfo:\t%s" % (self.indent, info))
printer_info = info
if dev.startswith ('ipp:'):
return self.getippqueue(dev, name, depth)
if depth == 0:
print
master = ''
if self.default_printer == printer_name:
master = 'MASTER'
self.master_printer = printer_name
self.printerpool.append([master, printer_name, printer_host,
printer_uri, printer_info])
# Settings
f = self.conn.getPPD(printer_name)
ppd = cups.PPD(f)
ppd.markDefaults()
groups = ppd.optionGroups
option2selection = dict()
for group in groups:
for opt in group.options:
selection = list(map(lambda x: x["text"], opt.choices))
option2selection[opt] = selection
self.printersettings[printer_name] = option2selection
def printer_pool(self):
"""
Ausgabe von status, printer_name, printer_host, printer_uri
und printer_info.
"""
return sorted(self.printerpool, reverse=True)
def printer_settings(self):
"""
Ausgabe von Drucker-Einstellungen und Auswahl-Einstellungen.
"""
return self.printersettings
def print2document(self, print_file):
"""
Ausführung von Druckauftrag.
"""
title = print_file.split("/")[-1]
try:
self.conn.printFile(self.master_printer, print_file,
title=title, options={})
except cups.IPPError as e:
print('Fehler bei Druckauftrag: %s' % e)
return
def main():
## Erledige Druckauftrag mit Standad-Drucker
# CUPS_Pool().print2document('/pfad/zu/test.pdf')
## Ausgabe Aller CUPS-Drucker
#printer_pool = CUPS_Pool().printer_pool()
try:
print(printer_pool)
except NameError:
pass
## Ausgabe der Drucker-Einstellungen und Auswahl-Einstellungen
## aller CUPS-Drucker.
## dict = (printer_name : {printer_setting : setting_selection})
#printer_settings = CUPS_Pool().printer_settings()
try:
print(printer_settings['MFC8860DN'])
except NameError:
pass
if __name__ == '__main__':
main()
Der Standard-Drucker, wird automatisch übergeben.
Bei Zeile 92:
Code: Alles auswählen
if depth == 0:
print
Grüße Nobuddy