- XSLT 82.6%
- Python 13.1%
- Shell 4.3%
| scripts | ||
| src/fatturapdf | ||
| tests | ||
| .gitignore | ||
| build-appimage-docker.sh | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
| test.sh | ||
FatturaPDF
FatturaPDF converts Italian FatturaPA invoice files from .xml, .p7m, or
.xml.p7m to human-readable HTML or PDF on Linux and macOS.
It provides:
fatturapdf, a CLI for conversion and GUI launch.fatturapdf-gui, a PySide6 desktop GUI with preview and export.- In-process CMS/P7M extraction with
asn1crypto, without shelling out to system OpenSSL during normal operation. - XSLT rendering with
lxml/libxslt and bundled FatturaPA stylesheets.
The generated PDF is a readable rendering of the invoice XML. It does not
replace the original signed .xml.p7m file. FatturaPDF extracts embedded XML
from CMS SignedData containers, but full legal digital-signature validation is
out of scope for v1.
Installation From Source
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
CLI Usage
fatturapdf invoice.xml.p7m -o invoice.pdf
fatturapdf invoice.xml -o invoice.pdf
fatturapdf --html invoice.xml.p7m -o invoice.html
fatturapdf invoice.xml.p7m --keep-html invoice.html -o invoice.pdf
fatturapdf --stylesheet-dir ./xslt invoice.xml -o invoice.pdf
fatturapdf --gui
If -o/--output is omitted, FatturaPDF writes next to the input using the same
base filename and a .pdf or .html suffix.
GUI Usage
fatturapdf-gui
# or
fatturapdf --gui
Use Open to select an .xml, .p7m, or .xml.p7m file. The invoice is
converted to temporary HTML and displayed in the preview. Use Save PDF or
Save HTML to export the rendered invoice.
The GUI shows user-facing errors for invalid XML, unsupported FatturaPA formats,
invalid CMS/P7M files, detached signatures without embedded XML, missing
stylesheets, and render failures. It also states that .p7m signatures are
extracted for display but not legally validated.
Updating Bundled XSLT Files
Bundled XSLT files live in:
src/fatturapdf/resources/xslt/
To download/update them from the official FatturaPA documentation page:
python scripts/fetch_xslt.py
The script uses only the Python standard library. It discovers current links from the official page where possible, and falls back to the known FPA12/FPR12 stylesheet URLs configured in the script.
Packaging Notes
PyInstaller needs to include package data and Qt WebEngine resources.
Linux CLI/GUI bundle:
CLI_ENTRY="$(python -c 'import shutil; print(shutil.which("fatturapdf"))')"
python -m PyInstaller --name fatturapdf \
--collect-all PySide6 \
--collect-data fatturapdf \
--onefile \
"$CLI_ENTRY"
Linux GUI windowed bundle:
GUI_ENTRY="$(python -c 'import shutil; print(shutil.which("fatturapdf-gui"))')"
python -m PyInstaller --name fatturapdf-gui \
--collect-all PySide6 \
--collect-data fatturapdf \
--windowed \
"$GUI_ENTRY"
macOS app bundle:
GUI_ENTRY="$(python -c 'import shutil; print(shutil.which("fatturapdf-gui"))')"
python -m PyInstaller --name FatturaPDF \
--collect-all PySide6 \
--collect-data fatturapdf \
--windowed \
--osx-bundle-identifier it.fatturapdf.app \
"$GUI_ENTRY"
Depending on the PySide6 and PyInstaller versions, you may need extra platform hooks for Qt WebEngine subprocesses. Test the produced bundle on a clean machine before distribution.
Development
Run tests:
pytest
Run lint:
ruff check .
Supported Formats
FatturaPDF detects:
FPA12FPR12
Detection first checks the root versione attribute, for example:
<FatturaElettronica versione="FPR12">
If that attribute is missing, it falls back to the FormatoTrasmissione
element.
Limitations / TODO
- Detached
.p7msignatures are not usable because they do not embed invoice XML. FatturaPDF returns a clear error in this case. - Full legal signature validation is not implemented in v1.
- Fattura semplificata (
FSM10) is not mapped yet. - PDF appearance follows the official XSLT stylesheets and Qt WebEngine print behavior.