Solved Convert PDF to CSV

Has anyone ever tried converting a PDF to CSV?

The PDF has a list of my bank transactions. I'm trying to import my transactions into a spreadsheet. I have downloaded a CSV file, but I get far too many columns which are difficult to identify. The PDF provides more info on each transaction and if I could produce a CSV out of it, it would be much more useful.


GROK recommends

pip install pdfplumber pandas

Anyone familiar with these programs?
 
You can produce the dataframe you want with pandas.read_csv, it provides enough options for your use case
(I use it)

If you are only interesting at the csv itself, you could use pure python, the structure of the csv provided from your bank will normally not change.
 
The pdfplumber project's README has an example. It creates an CSV file with info on every object in a PDF file.
So, that intermediate CSV can be used to get the actual CSV with pandas, which I've never dealt with.
 
I've used a pdf-to-text tool for this. pdftotext as part of popplerutils I think.
Yes I have used the same and created a text file which looks useful, and was thinking of breaking it up with a lot of sed/awk scripts but the prospect is pretty intimidating, so am looking at a way getting some dedicated program to do it for me.
 
YMMV...PDF stores both text and graphics, so it depends on how the document was created. If they were sneaky and stored the text as images then pulling the text becomes difficult/impossible. However, a document like that is usually quite large, comparatively.
 
YMMV...PDF stores both text and graphics, so it depends on how the document was created. If they were sneaky and stored the text as images then pulling the text becomes difficult/impossible. However, a document like that is usually quite large, comparatively.
I have managed to extract the required text so graphics do not play a part. It's basically a matter of getting it formatted in a way that I could make a CSV file out of it.
 
Looking at the text file extracted from the PDF I can identify what would be start of a new row as a line starting with 'Date'.

How would I export such a section as a row in a file for later parsing via awk?
 
The PDF has a list of my bank transactions. I'm trying to import my transactions into a spreadsheet. I have downloaded a CSV file, but I get far too many columns which are difficult to identify. The PDF provides more info on each transaction and if I could produce a CSV out of it, it would be much more useful.
It is unclear to me what exactly you are trying to say:
"I have downloaded a CSV file, but I get far too many columns which are difficult to identify."
This suggest that you are confronted with an unexpected number of values separated by commas.

"The PDF provides more info on each transaction [...]"
This suggest that each line which represents one transaction contains fundamentally more information than that same corresponding line in the CSV output. That sounds contradictionary or at least confusing.

Can you elaborate on these two issues?

It might help if you show:
  1. a small sanitized sample containing a header + 2–3 problematic records.
  2. the comparable lines of the pdf
While it is possible that the CSV generated output you are referring to is bad, it is hard to say if that might be the case without more specificity or a small example.

Did you know that awk(1) has CSV support that handles quoted values too?
 
*headscratch* :-/
CSV is a simple text file format for saving data (mostly numbers) in tables, supposing the number of columns in every line is the same. While PDF is a printer language. So first you need to get only what you need and can be sensefully transforemd into a PDF from the PDF (a table containing numbers), and cut the rest, since transform a whole PDF containing all kinds of other things into CVS IMO make no much sense, if it even would work.

My first try was simply straight forward:
Just open the according PDF with your PDF viewer, then mark the table with your mouse, then copy paste into a textfile.
This you may edit afterwards, add commas manually or with some macro, or sed, or else.

If there are more PDFs, so you want to automate the process, it can become a bit more complicated, since you need to also automate the process of finding the table in the PDF source. Perhaps it's better to transform the PDF first into a textfile on which you work, instead of trying to do all step in one job.
 
It is unclear to me what exactly you are trying to say:
"I have downloaded a CSV file, but I get far too many columns which are difficult to identify."
This suggest that you are confronted with an unexpected number of values seperated by commas.

"The PDF provides more info on each transaction [...]"
This suggest that each line which represents one transaction contains fundamentally more information than that same corresponding line in the CSV output. That sounds contradictionary or at least confusing.

Can you elaborate on these two issues?

It might help if you show:
  1. a small sanitized sample containing a header + 2–3 problematic records.
  2. the comparable lines of the pdf
While it is possible that the CSV generated output you are referring to is bad, it is hard to say if that might be the case without more specificity or a small example.

Did you know that awk(1) has CSV support that handles quoted values too?

Here are eight transactions. ';' is the column seperator. The last column is the transaction number. It is virtually impossible to line up the transaction amounts in the same column.

Code:
20-05-2022;20-05-2022;Zakup BLIK ORLEN STACJA NR 479 ELBLAG ref:66441197723;ORLEN STACJA NR 479 ELBLAG;72 1090 1489 0000 0000 4800 3393;-320,23;74863,70;587;                                                                                                           
20-05-2022;20-05-2022;Zakup BLIK ORLEN STACJA NR 4146 SZTUM ref:66441563333;ORLEN STACJA NR 4146 SZTUM;72 1090 1489 0000 0000 4800 3393;-8,99;74854,71;586;                                                                                                             
20-05-2022;20-05-2022;Zakup BLIK IBIS POZNAN STARE MIA UL. KAZIMIERZA WIELKIEGO ref:66450187536;IBIS POZNAN STARE MIA UL. KAZIMIERZA WIELKIEGO;72 1090 1489 0000 0000 4800 3393;-546,00;74308,71;585;                                                                   
20-05-2022;20-05-2022;Zakup BLIK JMP S.A. BIEDRONKA JMP S.A. BIEDRONKA 4730 ref:66457752520;JMP S.A. BIEDRONKA JMP S.A. BIEDRONKA 4730;72 1090 1489 0000 0000 4800 3393;-26,30;74282,41;584;                                                                             
22-05-2022;21-05-2022;Zakup BLIK NASZA WODNA 12 UL WODNA 12 l.A ref:66466296201;NASZA WODNA 12 UL WODNA 12 l.A;72 1090 1489 0000 0000 4800 3393;-67,00;74215,41;583;                                                                                                     
22-05-2022;21-05-2022;Zakup BLIK Stationary POS Targowa 72 ref:66470182903;Stationary POS Targowa 72;72 1090 1489 0000 0000 4800 3393;-80,47;74134,94;582;                                                                                                               
22-05-2022;22-05-2022;Zakup BLIK NASZA WODNA 12 UL WODNA 12 l.A ref:66488264973;NASZA WODNA 12 UL WODNA 12 l.A;72 1090 1489 0000 0000 4800 3393;-80,00;74054,94;581;                                                                                                     
23-05-2022;23-05-2022;Zakup BLIK Johnny Rockets Warszawa Lotnisko Chopina 39613 Żwirki i Wigury 1 ref:66505964398;Johnny Rockets Warszawa Lotnisko Chopina 39613 Żwirki i Wigury 1;72 1090 1489 0000 0000 4800 3393;-35,80;74019,14;580;

The PDF shows each transaction starting with the date and ending with a blank line. The number of lines differs depending on the nature of the transaction.

I'll look into your suggestion of CSV support in AWK and see if it gives me anything.
 
But in your sample data its always the same number of columns and the transaction amount is always the 6th column?
sko Many thanks for pointing that out!

The problem was that when importing I didn't pay proper attention to the delimiters and spaces and commas were included. In Polish currency ',' is a seperator as in '9,99' is used instead of '9.99' which is what I am used to.

You have saved me a lot of time. Thank you again.
 
Here are eight transactions. ';' is the column separator. The last column is the transaction number. It is virtually impossible to line up the transaction amounts in the same column.
When your bank can only generate a semicolon separated CSV, and not a comma separated CSV, you are prone to run into problems when a value/field itself contains a semicolon. I don't know if that will (ever) be an issue in this particular case. awk(1) (in base) can only tackle CSV input accurately when the input uses a comma as separator. If you have a semicolon as separator, then you'll likely have to look elsewhere like sysutils/goawk (perhaps lang/gawk but on the face of it that seems difficult).

AFAIK, there were/are two main problems processing CSV files with respect to various awk versions (but not limited to awk):
  1. values (fields) containing the comma separator
  2. values (fields) containing newlines of some sort; the precise "transition character(s)" differ per OS
So, in general, using the comma as a separator, the problem is using the comma itself inside a value, the "CSV-mode" of awk makes allowances for that. As a rule, it is not safe to use awk -F',' ... for CSV input processing.

Additionally, as it seems in your case, another separator (;) is being used. That may have been done to mitigate the "comma in value" problem that requires an escaping mechanism for the comma. But in general, even using a semicolon as separator needs an escaping-mechanism when a semicolon is used in a value.

For CSV processing using GoAWK:
  1. Modernizing AWK, a 45-year old language, by adding CSV support by Ben Hoyt 2022
  2. GoAWK's CSV and TSV file support
#1 is nice for initial overview of CSV processing using GoAWK.
#2 is to be used as a guide when you are working with sysutils/goawk

For GoAWK, the correct set up for use of CSV input with the use of ; as a separator seems to be:
Code:
[1-0] % goawk -i 'csv separator=;' '{ print NR,NF }' i1-m13
1 9
2 9
3 9
4 9
5 9
6 9
7 9
8 9
where the i1-m13 is your example CSV input from message 13.
As was mentioned by sko , this example run confirms a constant number of values/fields/columns: 9.

Using proper quoting, goawk seems capable to process values that contain a new line:
Code:
[1-0] % cat i9
a;"bla
blup";c
d;e;f
x;y;z
[2-0] % goawk -i 'csv separator=;' '{ print NR,NF }' i9
1 3
2 3
3 3


P.S. I'm completely unfamiliar with the mentioned pandas.read_csv
However, your problem seems to be about a CSV that has a small number a values/fields (=9), and also a small number of transactions; using goawk seems workable.[/icode]
 
awk(1) (in base) can only tackle CSV input accurately when the input uses a comma as separator.
you can always redefine the field separator via -F or 'FS'.
If the csv isn't properly sanitized *all* field separators are problematic. IMHO csv should *always* use quoted fields and either strip or escape the used quote character within the data.
 
I don't see how that can allow for using the separator inside a value; at least (at first glance) in an easy or straightforward way.
Edit: allowing for new lines inside values seems even more problematic.
Both is true. As I said: proper CSV data needs to be sanitized and/or escaped upon generation/exporting. Sadly there's a lot of broken csv exporters out there, various websites/'web-applications' being amongst the worst...
One way to get away with pretty much any character in the data would be encoding it e.g. in base64, but this bloats file size and complicates human consumption of the data (which usually is one of the key arguments for textual data instead of binary).
 
When your bank can only generate a semicolon separated CSV, and not a comma separated CSV, you are prone to run into problems when a value/field itself contains a semicolon.
When you download the CSV from the bank it asks what character you wish to use as a seperator.

A default is set, so it's easy to miss this prompt.
 
When you download the CSV from the bank it asks what character you wish to use as a seperator.

A default is set, so it's easy to miss this prompt.
Sometimes, none of the banks I have do that, but we use the . and , properly, so there's not as much of an issue. Honestly, it does feel kind of ironic how the Europeans are wrong on that one. Periods end things and commas group them with language, it's weird to have that backwards in languages that also end sentences with periods.

It may vary a bit, but I find the easiest thing to do is to look at that first line and see what it's doing. head -n 1 exported_doc.csv does the trick in terms of showing what sort of format to use. In my case the csv was automatically a bunch of fields enclosed in quotes and separated by commas that are extremely easy to strip out and sub with whatever I want if it's not suitable for my purpose with a combination of tr, sed and awk.
 
Sometimes, none of the banks I have do that, but we use the . and , properly, so there's not as much of an issue. Honestly, it does feel kind of ironic how the Europeans are wrong on that one. Periods end things and commas group them with language, it's weird to have that backwards in languages that also end sentences with periods.

It may vary a bit, but I find the easiest thing to do is to look at that first line and see what it's doing. head -n 1 exported_doc.csv does the trick in terms of showing what sort of format to use. In my case the csv was automatically a bunch of fields enclosed in quotes and separated by commas that are extremely easy to strip out and sub with whatever I want if it's not suitable for my purpose with a combination of tr, sed and awk.
Not all of Europe - we in the UK use commas to separate thousands :)
 
Back
Top