Luo PDF-tiedostoja malleista Python-ja Google-skripteillä

usein on hyödyllistä luoda PDF-tiedostoja Python-skripteistäsi. Olitpa luoda laskuja, kirjeitä, raportteja tai muita asiakirjoja, jotka sisältävät paljon muotoilun toistoa, mutta vain vähän dynaamista sisältöä, lisäämällä joitakin automaatio voi säästää monta tuntia.

tähän on muutama vaihtoehto. Tavallisia ovat:

  1. käytä PDF-kirjastoa kuten reportlab tuottamaan PDF-tiedostoja suoraan (esim. https://www.blog.pythonlibrary.org/2010/03/08/a-simple-step-by-step-reportlab-tutorial/)
  2. käytä HTML templating kirjasto kuten Jinja2 ja muuntaa HTML PDF (esim. katso http://pbpython.com/pdf-reports.html)
  3. käytä kolmannen osapuolen rajapintaa, kuten https://pdfgeneratorapi.com/.

vaihtoehdossa 1 PDF-tiedostojen luominen suoraan Pythonin sisältä voi tehdä muotoilusta hyvin vaikeaa. Sinun täytyy piirtää kaikki mitä tarvitset elementti kerrallaan, käyttäen koodia, ja vaikka sinulla on malli näyttää haluamallasi tavalla, se on vaikea ylläpitää.

Vaihtoehto 2 voi usein toimia paremmin, mutta sinun täytyy silti rakentaa Jinja HTML boilerplate, ja joskus HTML PDF muuntaminen ei tule ulos aivan odotetulla tavalla.

vaihtoehto 3 vaatii sinua rakentamaan mallin ensin verkkopalvelun verkkoliittymän avulla. Vaikka saat vedä ja pudota käyttöliittymä, se on melko kömpelö ja vaikea tehdä malli näyttää kuin haluat. Yleensä palvelun käytöstä joutuu myös maksamaan.

vaikka jokin ylläolevista vaihtoehdoista voi toimia kohdallasi, jos et pidä niistä, voit myös hakkeroida Google Driveen perustuvan dokumenttisukupolven API: n. Saat ilmaisen API: n, ja voit käyttää Google Docs: ia temppeliherätystyökalunasi, joka on melko tehokas ja sisältää monia olemassa olevia malleja esimerkiksi laskuille, kirjeille ja Ansioluetteloille.

aloitin laskupohjalla, jonka löysin netistä. Se näyttää tältä.:

 Google Docs Invoice Template

tässä opetusohjelmassa käymme läpi API: n luomisen, joka luo nämä laskut ja jonka avulla voit ohjelmallisesti lisätä laskun numeron ulkoisesta Python-skriptistä. Todellisuudessa sinun pitäisi tehdä sama monille muille aloille, mutta aloitamme yksinkertaisella esimerkillä esittelysyistä.

kirjoitamme muutaman rivin Google App Script-koodia ja muutaman rivin Python-koodia.

mallidokumentin luominen

käytä Googlen Asiakirjapohjiin rakennettua mallia, etsi netistä tarpeitasi vastaava asiakirja tai rakenna omasi osoitteessa docs.google.com. (tarvitset Google-tilin).

lisää paikkamerkit, jos tarvitset dynaamista tietoa. Alla olevassa esimerkissä olen lisännyt laskun nro {invoice_id} alkuperäisen asiakirjan ”456” id: n tilalle. Tässä syntaksissa ei ole mitään erikoista — käytämme perustason haku-ja korvaustoimintoa myöhemmin vaihtaaksemme tämän todellisiin tietoihin, joten käytä jotain, joka ei todennäköisesti näy lopullisessa dokumentissa.

merkitse muistiin asiakirjatunnuksesi, joka on korostettu osa URL-palkin kohdalla.

Laskupohja, jossa paikkamerkki

mukautetun Google-skriptin perustaminen

Siirry Google Driveen, paina ”uusi” vasemmassa yläkulmassa. Valitse kohdassa ”Lisää” ”Google Apps Script”, jos se on saatavilla, tai ”Connect more apps”, Jos et näe sitä.

 Connecting more apps

Search for ”apps script” and choose to connect it. Saatat nähdä joitakin varoitusviestejä, joissa kysytään, Luotatko itseesi. Sano, että tiedät.

lisäämällä Apps Script

kun voit luoda uuden App Script, näet oletetun tyhjän skriptin, joka näyttää seuraavanlaiselta.

Blank Google Apps Script

Poista siellä näkemäsi koodi ja korvaa se createDocument – funktiolla, joka näyttää seuraavalta.

function createDocument(invoice_id) { var TEMPLATE_ID = '1Ybq8r_SiWu4Z4-_Z6S0IW1L8FJywfpjPAATPCvvkKk8'; var documentId = DriveApp.getFileById(TEMPLATE_ID).makeCopy().getId(); drivedoc = DriveApp.getFileById(documentId); drivedoc.setName("Invoice " + invoice_id); doc = DocumentApp.openById(documentId); var body = doc.getBody(); body.replaceText('{invoice_id}', invoice_id); drivedoc.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.EDIT); return "https://docs.google.com/document/d/" + documentId + "/export?format=pdf";}

rivillä 2, Vaihda TEMPLATE_ID asiakirjatunnuksen kanssa, jonka kopioit templated Google Doc-dokumenttisi URL-palkista.

tämä koodi löytää templated Docin, luo siitä kopion ja asettaa tiedostonimen ”Invoice” plus mitä tahansa invoice_id ohitamme. Se avaa sitten uuden tiedoston DocumentApp-sovelluksen kautta (Drive-sovelluksen sijaan, jotta voimme todella saada tiedoston sisällön ja muokata niitä). Se etsii docista lisäämämme paikkamerkin ({invoice_id}) ja korvaa sen todellisella invoice_id, jonka funktio ottaa syötteeksi. Se asettaa asiakirjan julkisesti saataville ja palauttaa URL-osoitteen, joka menee suoraan kyseisen asiakirjan PDF-vientiin.

tämän funktion alapuolelle lisätään vielä yksi doGet. Edellistä funktiota voi nimetä miksi tahansa, mutta doGet on erikoisfunktio Google Apps-skripteissä, joten sille pitää antaa nimen tarkalleen doGet. Tämä toiminto käsittelee saapuvat verkkopyynnöt sovelluksemme käyttöönoton jälkeen.

doGet funktion koodi on seuraava Liitä tämä edellisen createDocument() – funktion alle.

function doGet(e) { var invoice_id = e.parameter.invoice_id; var url = createDocument(invoice_id); return ContentService.createTextOutput(url);}

tämä ottaa invoice_id-tunnuksen URL-parametrina, siirtää sen createDocument – funktiollemme, jonka juuri kirjoitimme, ja palauttaa luodun asiakirjan URL-osoitteen tavallisena tekstinä.

API: n julkaiseminen

”Julkaise” – valikosta, valitse ”Ota käyttöön verkkosovelluksena”

Ota käyttöön verkkosovelluksena

sinua pyydetään nimeämään projekti. Anna sille nimi kuten ”PDF API” tai mitä tahansa muuta haluat.

 projektin nimeäminen

näet uuden valikon, jossa voit määrittää verkkosovelluksesi käyttöönottovaihtoehdot.

Deploy options

lisää viestin kaltainen ”initial deploy” alle, jossa lukee ”New” ja valitse käyttöasetuksista ”kuka tahansa, jopa nimetön”. Jätä suoritusasetukset muotoon ”minä”.

Varoitus: Jos jaat linkin julkisella paikalla, ihmiset saattavat käyttää palvelua väärin ja roskapostittaa sitä automaattisilla pyynnöillä. Google voi lukita tilisi väärinkäytön varalta, jos näin tapahtuu, joten pidä linkki turvassa.

paina Ota käyttöön-painiketta ja kirjoita ylös URL, jonka näet seuraavassa ponnahdusikkunassa.

sovelluksesi URL

Add ”?invoice_id=1 ” URL-osoitteen loppuun ja vieraile selaimessasi. Sen pitäisi näyttää …

https://script.google.com/macros/s/AKfycbxDiKpTGqMijZmU8-0cPj06DBFjDOPYZJ9IFvhcO111GCh8jqxC/exec?invoice_id=1

jos kaikki meni hyvin, sinun pitäisi nähdä Google Docs linkki näytetään.

 vastaus verkkosovelluksestamme

jos käyt verkko-osoitteessa, tulee ladata PDF laskusta, jossa paikkamerkki on kytketty pois merkinnällä 1.

sovelluksen päivittäminen

jos sen sijaan näet virheen tai et saa vastausta, olet todennäköisesti tehnyt virheen koodissa. Voit muuttaa sitä ja päivittää käyttöönoton samalla tavalla kuin alun perin otit sen käyttöön. Päivitysnäyttö on vain hieman erilainen kuin käyttöönottonäyttö.

päivityksen käyttöönottovaihtoehdot

ainoa hankala asia on, että jokaisen tekemäsi muutoksen versioksi pitää valita ”uusi”. Jos teet muutoksia koodiin ja päivität edellisen version, muutokset eivät tule voimaan, mikä ei ole ilmeistä käyttöliittymästä. (Näet, että kesti muutaman yrittää saada tämä oikein.).

laskujen luominen Pythonista

voimme nyt luoda laskuja ja tallentaa ne paikallisesti Python-skriptistä. Seuraavassa koodissa kerrotaan, miten for – silmukassa luodaan kolme laskua.

import requestsurl = "https://script.google.com/macros/s/AKfycbyYL5jhEstkuzZAmZjo0dUIyAmzUc1XL5B-01fHRHx8h63cieXc/exec?invoice_id={}"invoice_ids = for invoice_id in invoice_ids: print("processing ", invoice_id) response = requests.get(url.format(invoice_id)) print("file generated") response = requests.get(response.content) print("file downloaded") with open("invoice{}.pdf".format(invoice_id), "wb") as f: f.write(response.content)

huomaa, että luonti-ja latausprosessi on melko hidas, joten jokainen laskusi vie muutaman sekunnin.

olet luultavasti huomannut, että tämä on melkoinen ”hacky” ratkaisu luoda PDF-tiedostoja Pythonin sisältä. ”Replace” – toiminto on melko rajallinen verrattuna oikeaan templating-kieleen, ja tietojen välittämisessä get-pyynnön kautta on myös rajoituksia. Jos läpäiset jotain monimutkaisempaa kuin laskun tunnus, sinun URL koodata tiedot ensin. Voit tehdä tämän Pythonissa käyttämällä urllib.parse – moduulia. Python-komentosarjan muunnos monimutkaisempien tietojen käsittelemiseksi on seuraava.

import requestsimport urllib.parseurl = "https://script.google.com/macros/s/AKfycbyYL5jhEstkuzZAmZjo0dUIyAmzUc1XL5B-01fHRHx8h63cieXc/exec?"invoice_ids = for invoice_id in invoice_ids: print("processing ", invoice_id) payload = {"invoice_id": invoice_id} u = url + urllib.parse.urlencode(payload) response = requests.get(u) print("file generated") response = requests.get(response.content) print(response.content) print("file downloaded") with open("invoice{}.pdf".format(invoice_id), "wb") as f: f.write(response.content)

mutta on vielä rajoituksia siitä, millaista tietoa ja kuinka paljon voit välittää vain käyttämällä URL-osoitteita, joten sinun olisi muutettava komentosarjaa käyttääksesi sen sijaan POST-pyyntöjä, jos lähetät paljon dynaamista dataa.

se on myös melko hidas verrattuna joihinkin muihin alussa käsittelemiimme menetelmiin, ja Googlella on joitakin rajoituksia sille, kuinka monta tiedostoa voit luoda automaattisesti tällä tavalla.

tästä huolimatta Google-dokumenttien tuottaminen voi olla nopeaa ja tehokasta, joten sinun on arvioitava tradeoffit itse.

huomaa myös, että tämä on melko keksitty esimerkki, jossa olisimme voineet ajaa Python-komentosarjan Googlen ekosysteemistä käsin, ja välttää tarpeen perustaa julkinen API, jota voitaisiin mahdollisesti käyttää väärin, jos muut ihmiset löytäisivät URL: n. Sinulla saattaa kuitenkin olla olemassa oleva Python-sovellus, joka ei ole Googlen isännöimä, että sinun on yhdistettävä automaattisesti luotuihin PDF-tiedostoihin, ja tämän menetelmän avulla voit silti perustaa Googlen ekosysteemiin itsenäisen ”microservice” – palvelun, joka mahdollistaa helpon PDF-generoinnin.

johtopäätös