Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix parse_csv in templates to parse numbers #205

Merged
merged 3 commits into from
Aug 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion fpdf/fpdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,7 @@ def _preload_font_styles(self, txt, markdown):
to avoid repeating this processing later on.
"""
if not txt or not markdown:
return ((txt, self.font_style, bool(self.underline)),)
return tuple([[txt, self.font_style, bool(self.underline)]])
prev_font_style = self.font_style
styled_txt_frags = tuple(self._markdown_parse(txt))
page = self.page
Expand Down
16 changes: 12 additions & 4 deletions fpdf/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
__license__ = "LGPL 3.0"

import csv
import locale
import warnings

from .errors import FPDFException
from .fpdf import FPDF
from .util import try_to_type


def rgb(col):
Expand Down Expand Up @@ -64,7 +66,7 @@ def load_elements(self, elements):
self.elements = elements
self.keys = [v["name"].lower() for v in self.elements]

def parse_csv(self, infile, delimiter=",", decimal_sep="."):
def parse_csv(self, infile, delimiter=",", decimal_sep=".", encoding=None):
"""Parse template format csv file and create elements dict"""
keys = (
"name",
Expand All @@ -87,13 +89,17 @@ def parse_csv(self, infile, delimiter=",", decimal_sep="."):
)
self.elements = []
self.pg_no = 0
with open(infile) as f:
if encoding is None:
encoding = locale.getpreferredencoding()
with open(infile, encoding=encoding) as f:
for row in csv.reader(f, delimiter=delimiter):
kargs = {}
for i, v in enumerate(row):
if not v.startswith("'") and decimal_sep != ".":
v = v.replace(decimal_sep, ".")
kargs[keys[i]] = v.strip()
stripped_value = v.strip()
typed_value = try_to_type(stripped_value)
kargs[keys[i]] = typed_value
self.elements.append(kargs)
self.keys = [v["name"].lower() for v in self.elements]

Expand Down Expand Up @@ -174,7 +180,9 @@ def render(self, outfile=None, dest=None):
pdf.set_font("helvetica", "B", 16)
pdf.set_auto_page_break(False, margin=0)

for element in sorted(self.elements, key=lambda x: x["priority"]):
sorted_elements = sorted(self.elements, key=lambda x: x["priority"])

for element in sorted_elements:
element = element.copy()
element["text"] = self.texts[pg].get(
element["name"].lower(), element["text"]
Expand Down
14 changes: 14 additions & 0 deletions fpdf/util.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import locale
from typing import Union, Iterable

try_to_type_known_types = [
int,
float,
]


def try_to_type(value):
for known_type in try_to_type_known_types:
try:
return known_type(value)
except ValueError:
pass
return value


def substr(s, start, length=-1):
if length < 0:
Expand Down
8 changes: 4 additions & 4 deletions test/template/mycsvfile.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
line0;T;20.0;13.0;190.0;13.0;times;10.0;0;0;0;0;65535;C;;0
line1;T;20.0;67.0;190.0;67.0;times;10.0;0;0;0;0;65535;C;;0
name0;T;21;14;104;25;times;16.0;0;0;0;0;0;C;;2
title0;T;64;26;104;30;times;10.0;0;0;0;0;0;C;;2
line0;L;20.0;12.0;190.0;12.0;times;0.5;0;0;0;0;65535;C;;0
line1;L;20.0;36.0;190.0;36.0;times;0.5;0;0;0;0;65535;C;;0
name0;T;21;14;104;25;times;16.0;0;0;0;0;0;L;name;2
title0;T;21;26;104;30;times;10.0;0;0;0;0;0;L;title;2
Binary file modified test/template/template_nominal_csv.pdf
Binary file not shown.
8 changes: 7 additions & 1 deletion test/template/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,13 @@ def test_template_nominal_csv(tmp_path):
tmpl = Template(format="A4", title="Sample Invoice")
tmpl.parse_csv(HERE / "mycsvfile.csv", delimiter=";")
tmpl.add_page()
assert_pdf_equal(tmpl, HERE / "template_nominal_csv.pdf", tmp_path)
tmpl.render()
assert_pdf_equal(tmpl.pdf, HERE / "template_nominal_csv.pdf", tmp_path)
tmpl = Template(format="A4", title="Sample Invoice")
tmpl.parse_csv(HERE / "mycsvfile.csv", delimiter=";", encoding="utf-8")
tmpl.add_page()
tmpl.render()
assert_pdf_equal(tmpl.pdf, HERE / "template_nominal_csv.pdf", tmp_path)


def test_template_code39(tmp_path): # issue-161
Expand Down