Jak tisknout štítky/účtenku přímo z webového prohlížeče

Uvažovali jste někdy o tom, napsat si vlastní pokladní systém, který by běžel jen na webu ? Opět se blíží další vlna EET, která se nyní týká všech a které by se nemělo jít vyhnout ani placením převodem. Mít vlastní pokladní systém nic složitého není a bez potíží vám v něm může fungovat i čtečka čárových kódů na zboží. Ta totiž často funguje jako běžná klávesnice, která ten kód napíše za vás.

Nebo můžete chtít udělat skladový systém, kde budete načítat nebo i tisknout štítky na balíky.

Jak si ale poradit s tiskem na speciální tiskárně s úzkou rolí ?

Běžný tiskový dialog webových prohlížečů a běžný tiskový systém často nejsou vhodnými nástroji pro tisk na speciálních tiskárnách co tisknou na úzkou dlouhou roli papíru, nebo nalepovací štítky.

Pokud chcete mít naprostou jistotu jak bude výtisk vypadat a jak bude na papíře rozmístěn, může být řešení vygenerovat nejdříve PDF a to teprve tisknout. Což je dost nešikovné, pokud je tato operace častá.

Chci se podělit o řešení, které používáme již necelých 20 let a které, pokud by jej někdo hledal, není úplně snadné objevit.

Problém je totiž v tom, jak z webu, který běží na serveru přenést potřebné informace do lokálního počítače, do lokálně běžícího skriptu, který by tisk mohl snadno provést. Webový prohlížeč se snaží běh javascriptu a webovou stránku co nejvíce izolovat od lokálního počítače kvůli bezpečnosti. Novější Chrome i Firefox už obsahují nějakou podporu v API, stále to není moc elegantní řešení, které by fungovalo s libovolnou tiskárnou. Krom toho je to řešení šité na míru jednomu nebo druhému webovému prohlížeči bez možnosti využít tisk i z jiných aplikací.

Běžné řešení bývá rozběhnout si na lokálním počítači web, který běží jen na localhostu a je dostupný jen lokálně. Tisk lze pak spustit pouhým kliknutím na odkaz na localhost. Odkaz pak obsahuje parametry s informacemi potřebnými pro tisk. Opět můžete ale narážet na problém s bezpečností a tím, že webové prohlížeče mohou takovému použití bránit. Nevím jaká je situace v současnosti, ale v minulosti jsem s takovými obstrukcemi setkal. Podobně jako bylo/je v módě tvrdit, že lepší bezpečnosti dosáhneme pravidelnou změnou hesel, nebo vkládáním speciálních znaků do hesel, nedivil bych se, kdyby někdo časem např. vymyslel další komplikaci, jako že volat localhost bez https může být bezpečnostní riziko. Samozřejmě je to nadsázka. Chci ale říci, že někdy může být nutné vybírat přednostně taková řešení, u kterého je zablokování z důvodu bezpečnosti méně pravděpodobné. A také samozřejmě i zprovozňování i jednoduché webu je zbytečná komplikace, navíc zjevně v tomto případě bude nutné udělat webové aplikaci práva k tisku nebo zařízení tiskárny.

Vlastní URL schéma či protokol

Existuje ale něco lepšího. Stačí si zaregistrovat na daném počítači vlastní URL/URI schéma (vlastní protokol). Podobně jak je možné z libovolné aplikace kliknout na email, které otevře váš mailový klient s předvyplněným emailem, stejným způsobem je možné zavolat lokální skript obstarávající tisk na lokální tiskárně. Místo emailu bude tomuto skriptu předán text k vytištění. A výsledek je, že pak mohu z libovolné aplikace, včetně např. LibreOfficeCalc jedním klikem zavolat svůj vlastní skript a předat mu potřebné informace. Např. text k tisku. Pokud potřebuji vytisknout delší text, nebo třeba i obrázek, mohu jej zakódovat pomocí Base64.

Prostě je to způsob, jak předat nějaké informace z webové stránky lokálními skriptu, který pak může zařídit vše potřebné.

  • vyplnit PDF formulář zaslanými daty a poslat je běžnou lokální tiskárny, tentokráte s využitím CUPS.
  • pomocí USB nebo lokální počítačové sítě, odeslat z vašeho mobilního telefonu připravené SMS, nebo vytočit konkrétní telefonní číslo
  • přepnout stav lokálně připojeného relátka, řízeného přes USB. Skript může řídit celou sekvenci přepínání relátek, které provedou složitější operaci.

Postup registrace vlastního URL schéma / protokolu

Pro skriptování používám jazyk ruby, ale je možné použít libovolné. Samotný skript může vypadat např. takto:

#!/usr/local/bin/ruby2.1
require '/var/www/oprint_lib.rb'
 
printer = OPrinter.new(:logger => Logger.new('/var/log/oprint'),
                       :param => ARGV[0])
printer.run do |type|
  case type
  when 'jehlickova'
    OPrinter::DotmatrixBase64ToBlockDevice.new(:device => '/dev/dot0', :diacritics => true)
  when 'stitek'
    OPrinter::PinPnmToRawPrinter.new(:printer_name => 'Brother_raw')
    #OPrinter::PinPostScriptToCUPS.new(:printer_name => 'Brother_PT-2420PC')
  end
end

Samotný tisk se pak vyvolá kliknutím na odkaz "otisk://jehlickova/Base64_encoded_content_to_print", pokud budu chtít tisknout na staré jehličkové tiskárně. Nebo "otisk://stitek/12468" pokud budu chtít vytisknout štítek s číslem 12468 např. na tiskárně Brother_PT-2420PC. Samotný tisk dělá knihovna v ruby a ke způsobu jak proběhne se ještě vrátím. Nyní se chci zaměřit na to, jak docílit spuštění tohoto skriptu s předáním parametrů.

[Desktop Entry]
Name=otisk
Comment=Tisknu lokálně
Exec=otisk.rb %U
Terminal=false
Type=Application
Encoding=UTF-8
Categories=Network;Application;
MimeType=x-scheme-handler/otisk;
X-KDE-Protocols=otisk

Registrace protokolu:

xdg-mime default otisk.desktop x-scheme-handler/otisk
update-desktop-database ~/.local/share/applications/
xdg-mime query default x-scheme-handler/otisk

Test

xdg-open 'otisk://stitek/889639'
<a href="otisk://stitek/889639">Vytisknout štítek</a>
 
otisk_clanek.txt · Last modified: by root