Har ni ett gammalt eller ett ekonomisystem som är svårt att integrera?
Nedan finns kod för att läsa av innehållet i en PDF. Detta kommer inte fungera rakt av för din lösning, men kan ge inspiration.
Om du behöver hjälp så finns mina kontaktuppgifter på den här sidan eller Linkedin.
#Created by Karl Sjökvist
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter, XMLConverter, HTMLConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from io import BytesIO
import os
import glob
import xml.etree.ElementTree as ET
def convert_pdf(path, format='xml', codec='utf-8', password=''):
rsrcmgr = PDFResourceManager()
retstr = BytesIO()
laparams = LAParams()
if format == 'text':
device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
elif format == 'html':
device = HTMLConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
elif format == 'xml':
device = XMLConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
else:
raise ValueError('provide format, either text, html or xml!')
fp = open(path, 'rb')
interpreter = PDFPageInterpreter(rsrcmgr, device)
maxpages = 0
caching = True
pagenos=set()
for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
interpreter.process_page(page)
text = retstr.getvalue().decode()
fp.close()
device.close()
retstr.close()
return text
#Analyserar och flyttar de analyserade filerna till klara efter att en xml har skapats av innehållet
PATH = "C:/Users/karl.sjokvist/Desktop/read pdf/"
if not os.path.exists('klara'):
os.makedirs('klara')
pdffiles = (glob.glob(PATH + "*.pdf")) #Listar alla filer
for pdf in pdffiles:
text = convert_pdf(pdf) #Anropet till konverteringen
filename = pdf.split("\\")
filename = filename[1].split(".")
filename = filename[0]
print ("påbörjar analys av " + filename)
f = open(filename + ".xml", "w")
text = text.replace("utf-8", "ISO-8859-1")
text+="</pages>" #Var tvungen att lägga till detta då det finns en bugg
f.write(text)
f.close()
os.replace(pdf, PATH+"klara/" + filename + ".pdf") #Flyttar filen
#XML query för att få fram datan
tree = ET.parse(filename + ".xml")
root = tree.getroot()
raknadesidor = 0
sidor = 1
#Räknar sidor i PDFn
for value in root.iter('page'):
raknadesidor+=1
#Går genom alla sidor enskillt
while sidor <= raknadesidor:
print ("Sida" + str(sidor))
for value in root.iter('page'):
if value.attrib['id'] == str(sidor): #Sidorna på PDFen
#För att få fram alla kostnadsrader
#Artikelrader
kostnadsrader = []
for subvalue in value.iter('textline'):
if subvalue.attrib['bbox'].startswith("53.150"): #Kordinaterna på PDFen
textstring = ""
for text in subvalue.iter('text'): #Slår ihop indeviduella tecken till rader
textstring+=text.text
textstring = textstring[:-1]#Tar bort nya radbytet
kostnadsrader.append(textstring)
firstindex = kostnadsrader.index("Artikel") #Första radindex
secondindex = [i for i in kostnadsrader if i.startswith('Moms')]
secondindex = kostnadsrader.index(secondindex[0])
kostnadsrader = kostnadsrader[firstindex + 1:secondindex] #tar bort allt innan och efter index
print (kostnadsrader)
#Counts the numbers of type rows i.e. rows that has numbers
posoffirstnum = None
countrows = 0
for i in kostnadsrader:
if i[0].isnumeric():
if i[-1].isnumeric():
if posoffirstnum == None:
posoffirstnum = countrows
countrows+=1
#Benämning
benamningsrader = []
for subvalue in value.iter('textline'):
if subvalue.attrib['bbox'].startswith("130.400"): #Kordinaterna på PDFen
textstring = ""
for text in subvalue.iter('text'): #Slår ihop indeviduella tecken till rader
textstring+=text.text
textstring = textstring[:-1]#Tar bort nya radbytet
benamningsrader.append(textstring)
firstindex = benamningsrader.index("Benämning") #Första radindex
benamningsrader = benamningsrader[firstindex + 1:] #tar bort allt ibörjan och slutet av array
print (benamningsrader)
#antal
antalrader = []
for subvalue in value.iter('textline'):
if subvalue.attrib['bbox'].startswith("360.200") or subvalue.attrib['bbox'].startswith("360.650") or subvalue.attrib['bbox'].startswith("365.150") or subvalue.attrib['bbox'].startswith("364.700"): #Kordinaterna på PDFen
textstring = ""
for text in subvalue.iter('text'): #Slår ihop indeviduella tecken till rader
textstring+=text.text
textstring = textstring[:-1]#Tar bort nya radbytet
textstring = textstring.replace(" St","");
textstring = textstring.replace(" ","");
antalrader.append(textstring)
print (antalrader)
#enhet
enheter = []
for subvalue in value.iter('textline'):
if subvalue.attrib['bbox'].startswith("365.150") or subvalue.attrib['bbox'].startswith("391.400") or subvalue.attrib['bbox'].startswith("360.650") or subvalue.attrib['bbox'].startswith("360.200"): #Kordinaterna på PDFen
textstring = ""
for text in subvalue.iter('text'): #Slår ihop indeviduella tecken till rader
textstring+=text.text
textstring = textstring[:-1]#Tar bort nya radbytet
enheter.append(textstring)
#Rensar onödig informaton från enhet
enheterloop = 0
while enheterloop < len(enheter):
if "st" in enheter[enheterloop]:
enheter[enheterloop] = "st"
if "tim" in enheter[enheterloop]:
enheter[enheterloop] = "tim"
if "skif" in enheter[enheterloop]:
enheter[enheterloop] = "skif"
if "St" in enheter[enheterloop]:
enheter[enheterloop] = "St"
if enheter[enheterloop] != "st" and enheter[enheterloop] != "tim" and enheter[enheterloop] != "skif" and enheter[enheterloop] != "St":
del enheter[enheterloop]
if len(enheter) >=1:
enheterloop-=1
enheterloop+=1
print (enheter)
#pris
prisrader = []
for subvalue in value.iter('textline'):
if subvalue.attrib['bbox'].startswith("417.150") or subvalue.attrib['bbox'].startswith("421.650") or subvalue.attrib['bbox'].startswith("426.150"): #Kordinaterna på PDFen
textstring = ""
for text in subvalue.iter('text'): #Slår ihop indeviduella tecken till rader
textstring+=text.text
textstring = textstring[:-1]#Tar bort nya radbytet
prisrader.append(textstring)
print (prisrader)
#skriva ut raderna
rader = 0
offset = 0
print ("Skriver ut raderna")
while rader < len(kostnadsrader):
rad = kostnadsrader[rader]
if rader >= posoffirstnum:
if offset < len(benamningsrader):
rad = rad + " " + benamningsrader[offset] + " " + antalrader[offset] + " " + enheter[offset] + " " + prisrader[offset]
offset+=1
rader+=1
print (rad)
print ("klar med analys\n")
sidor+=1