Lag PDF-filer fra maler Med Python Og Google-Skript

Ofte er DET nyttig å lage PDF-filer fra Python-skriptene dine. Enten du lager fakturaer, brev, rapporter eller andre dokumenter som inneholder mye formateringsrepetisjon, men bare litt dynamisk innhold, kan det å legge til litt automatisering spare deg for mange timer.

Du har noen alternativer for dette. De vanlige er:

  1. Bruk ET PDF-bibliotek som reportlab til å generere PDF-filer direkte (f. eks. https://www.blog.pythonlibrary.org/2010/03/08/a-simple-step-by-step-reportlab-tutorial/)
  2. Bruk EN HTML templating bibliotek som Jinja2 og konvertere FRA HTML TIL PDF (f. eks se http://pbpython.com/pdf-reports.html)
  3. Bruk en TREDJEPARTS API som https://pdfgeneratorapi.com/.

for Alternativ 1 kan generering Av Pdf-Filer direkte fra Python gjøre formatering svært vanskelig. Du må tegne alt du trenger element for element, ved hjelp av kode, og selv når du har en mal som ser slik du vil ha det, er det vanskelig å vedlikeholde.

Alternativ 2 kan ofte fungere bedre, men Du må fortsatt bygge Jinja HTML-boilerplaten, og NOEN GANGER KOMMER HTML TIL PDF-konvertering ikke ut som du forventet.

alternativ 3 krever at du bygger malen først ved hjelp av en nettjenestes webgrensesnitt. Selv om du får et dra-og-slipp-grensesnitt, er det ganske clunky og vanskelig å få malen til å se ut som du vil. Vanligvis må du også betale for å bruke tjenesten.

mens et av alternativene ovenfor kan fungere for deg, hvis du ikke liker noen av dem, kan du også hacke sammen et dokumentgenererings-API basert På Google Disk. Du får en GRATIS API, og Du kan bruke Google Docs som ditt templerende verktøy, som er ganske kraftig og har mange eksisterende maler for ting som fakturaer, brev og Cv.

jeg startet med en fakturamal som jeg fant på nettet. Det ser slik ut:

Google Docs Faktura Mal

i denne opplæringen går vi gjennom å lage EN API som genererer disse fakturaene og lar deg programmatisk sette inn fakturanummeret fra et eksternt Python-skript. I virkeligheten må du gjøre det samme for mange av de andre feltene, men vi starter med et enkelt eksempel av demonstrasjonsgrunner.

Vi skal skrive noen få linjer Med Google App Script-kode, og noen få linjer Med Python-kode.

Opprette et maldokument

Bruk En Av De innebygde Google-Dokumentmalene, søk på nettet etter en Som passer dine behov, eller bygg din egen over på docs.google.com. (Du trenger En Google-Konto).

Legg til plassholdere der du trenger dynamisk informasjon. I eksemplet nedenfor har jeg lagt FAKTURA no {invoice_id} i stedet for » 456 » id som jeg hadde på originaldokumentet. Det er ikke noe spesielt med denne syntaksen-vi bruker en grunnleggende søk og erstatt-funksjon senere for å bytte ut dette for den virkelige informasjonen, så bruk noe som er usannsynlig å faktisk vises i det endelige dokumentet.

legg merke til dokument-id-en din, som er den uthevede delen i URL-linjen.

Fakturamal med plassholder

Sette opp et tilpasset Google-Skript

Gå Til Google Disk, trykk » Ny » øverst til venstre. Under» Mer «velger Du» Google Apps Script «hvis Det er tilgjengelig, eller» Koble til flere apper » hvis du ikke ser Det.

Koble til flere apper

Søk etter «apps script» og velg å koble det til. Du kan se noen advarsler som spør om du stoler på deg selv. Si at du gjør det.

 Legge Til Apps Script

når du kan opprette et Nytt Appskript, ser du et standard tomt skript som ser ut som følger.

Tomt Google Apps Script

Slett koden du ser der, Og erstatt den med en createDocument – funksjon som ser ut som følger.

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";}

på linje 2 bytter du ut TEMPLATE_ID med dokument-IDEN du kopierte FRA URL-linjen på det malede Google-Dokumentet.

denne koden finner malen doc, oppretter en kopi av den og setter filnavnet til «Faktura» pluss hva invoice_id vi passerer inn. Den åpner deretter den nye filen Gjennom DocumentApp (i stedet For Drive-Appen, slik at vi faktisk kan få innholdet i filen og redigere dem). Den søker doc for plassholderen vi la til ({invoice_id}) og erstatter den med den faktiske invoice_id som funksjonen tar som inngang. Den angir deretter at dokumentet skal være offentlig tilgjengelig og returnerer EN URL-ADRESSE som vil gå direkte til EN PDF-eksport for dokumentet.

under denne funksjonen legger du til en annen som heter doGet. Mens den forrige funksjonen kan bli kalt noe, er doGet en spesiell funksjon I Google Apps-Skript, så du må nevne den nøyaktig doGet. Denne funksjonen vil håndtere innkommende webforespørsler etter at vi har distribuert vår app.

koden for doGet – funksjonen er som følger. Lim inn dette under den forrige createDocument() – funksjonen.

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

dette tar inn invoice_id som en url-parameter, sender dette videre til vår createDocument funksjon som vi nettopp skrev, og returnerer URL-ADRESSEN til det opprettede dokumentet som ren tekst.

Publisere VÅR API

fra» Publiser «- menyen, velg «Distribuer som web app»

Distribuer som web app

Du blir bedt om å gi prosjektet et navn. Gi det et navn som «PDF API» eller noe annet du vil ha.

 Navngi prosjektet

du vil se en ny meny for å angi alternativene for distribusjon av webappen.

Distribusjonsalternativer

Legg til en melding som «initial deploy» under der det står » Ny «og velg» Hvem som helst, selv anonym » fra tilgangsinnstillingene. La Kjøringsinnstillingene være som «Meg».

Advarsel: hvis du deler koblingen på et offentlig sted, kan folk misbruke tjenesten og sende den i spam med automatiske forespørsler. Google kan låse kontoen din for misbruk hvis dette skjer, så hold koblingen trygg.

Trykk På Distribuer-knappen og noter NETTADRESSEN du ser på neste popup.

appens URL

Legg til «?invoice_id=1 » til slutten AV NETTADRESSEN og besøk den i nettleseren din. Det skal se ut som noe

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

hvis alt gikk bra, bør Du se En Google Docs-lenke som vises.

 Svar fra vår webapplikasjon

hvis DU besøker NETTADRESSEN, skal en PDF av fakturaen med plassholderen slått ut med 1 lastes ned.

Oppdatere programmet

hvis du ser en feil i stedet, eller ikke får svar, har du sannsynligvis gjort en feil i koden. Du kan endre den og oppdatere distribusjonen på samme måte som du først distribuerte den. Oppdateringsskjermen er bare litt forskjellig fra distribuer-skjermen.

 Oppdater distribusjonsalternativer

det eneste vanskelige er at du må velge «Ny» som versjon for hver endring du gjør. Hvis du Gjør endringer i koden og Oppdaterer en tidligere versjon, trer ikke endringene i kraft, noe SOM ikke er tydelig fra BRUKERGRENSESNITTET. (Du kan se det tok meg noen forsøk på å få dette riktig .).

Opprette fakturaer fra Python

Vi kan nå lage fakturaer og lagre dem lokalt fra Et Python-skript. Følgende kode viser hvordan du genererer tre fakturaer i en loop for.

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)

Merk at opprettings-og nedlastingsprosessen er ganske treg, så det tar noen sekunder for hver faktura du oppretter.

du har sikkert lagt merke til at dette er litt av en «hacky» løsning for å generere PDF-filer fra Innsiden Python. «Erstatt» – funksjonaliteten er ganske begrenset i forhold til et riktig malspråk, og overføring av data gjennom en get-forespørsel har også begrensninger. Hvis du går gjennom noe mer komplisert ENN en faktura-ID, MÅ DU URL-kode dataene først. Du kan gjøre Dette i Python ved hjelp av modulen urllib.parse. Et eksempel modifikasjon Av Python script for å håndtere mer kompliserte data er som følger.

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)

Men det er fortsatt begrensninger på hva slags data og hvor mye du kan passere bare ved Hjelp Av Nettadresser, så du må endre skriptet for å bruke POSTFORESPØRSLER i stedet hvis du sendte mye dynamisk data.

Det er også ganske sakte sammenlignet med noen av de andre metodene vi diskuterte i begynnelsen, Og Google har noen begrensninger på hvor mange filer du kan lage automatisk på denne måten.

når det er sagt, å kunne generere maler ved Hjelp Av Google Docs kan være rask og kraftig, så du må vurdere avvikene for deg selv.

vær Også oppmerksom på at dette er et ganske konstruert eksempel, hvor vi kunne ha kjørt Python-skriptet fra Google-Økosystemet, og unngått å måtte sette opp en offentlig vendt API som potensielt kunne bli misbrukt hvis andre oppdaget NETTADRESSEN. Du kan imidlertid ha et eksisterende Python-program, ikke vert På Google, som du må koble til med automatisk genererte PDF-filer, og denne metoden lar deg fortsatt sette opp en selvstendig «microservice» i Google-økosystemet som muliggjør enkel PDF-generering.

Konklusjon