OfficeIMO.Invoicing 3.4.5

Prefix Reserved
dotnet add package OfficeIMO.Invoicing --version 3.4.5
                    
NuGet\Install-Package OfficeIMO.Invoicing -Version 3.4.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OfficeIMO.Invoicing" Version="3.4.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OfficeIMO.Invoicing" Version="3.4.5" />
                    
Directory.Packages.props
<PackageReference Include="OfficeIMO.Invoicing" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OfficeIMO.Invoicing --version 3.4.5
                    
#r "nuget: OfficeIMO.Invoicing, 3.4.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OfficeIMO.Invoicing@3.4.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OfficeIMO.Invoicing&version=3.4.5
                    
Install as a Cake Addin
#tool nuget:?package=OfficeIMO.Invoicing&version=3.4.5
                    
Install as a Cake Tool

OfficeIMO.Invoicing

Create, read, edit and convert electronic invoices with one typed .NET model. The core has no external runtime dependencies and supports .NET Standard 2.0, .NET 8, .NET 10 and .NET Framework 4.7.2.

Install

dotnet add package OfficeIMO.Invoicing --version 3.4.4

This package does not depend on a PDF engine or an external validation runtime.

Build from source

From the repository root, pack the project into a local feed, then add that package to your application:

dotnet pack OfficeIMO.Invoicing/OfficeIMO.Invoicing.csproj -c Release -o artifacts/invoice-feed
dotnet add path/to/Application.csproj package OfficeIMO.Invoicing --source artifacts/invoice-feed

Create invoice XML

InvoiceXmlOptions.GetSupportedTargets() returns the valid combinations of specification release, syntax and profile from the same contract used by the options constructor. Use this catalog for format selection; projection rejects data loss by default.

using OfficeIMO.Invoicing;

var invoice = new Invoice {
    Number = "INV-001",
    IssueDate = new DateTime(2026, 9, 10),
    DueDate = new DateTime(2026, 10, 10),
    Currency = "EUR",
    Seller = new InvoiceParty {
        Name = "Example Seller",
        Address = new InvoiceAddress { CountryCode = "DE" }
    },
    Buyer = new InvoiceParty {
        Name = "Example Buyer",
        Address = new InvoiceAddress { CountryCode = "DE" }
    }
};
invoice.Seller.TaxRegistrations.Add(
    new InvoiceTaxRegistration("DE123456789", InvoiceTaxRegistration.VatScheme));
invoice.Payments.Add(new InvoicePayment {
    MeansCode = "58",
    Reference = invoice.Number,
    Account = new InvoiceBankAccount { Identifier = "DE79000000001234567890" }
});
invoice.Lines.Add(new InvoiceLine {
    Id = "1", Name = "Consulting", Quantity = 1m, UnitPrice = 100m,
    Tax = new InvoiceTaxCategory { Code = "S", Rate = 19m }
});
byte[] cii = InvoiceSerializer.Write(invoice, new InvoiceXmlOptions(
    InvoiceSpecificationRelease.FacturX_1_09_2_Zugferd_2_5_2,
    InvoiceSyntax.Cii,
    InvoiceProfile.En16931));
byte[] ubl = InvoiceSerializer.Write(invoice,
    new InvoiceXmlOptions(
        InvoiceSpecificationRelease.En16931_1_3_16,
        InvoiceSyntax.Ubl,
        InvoiceProfile.En16931));

Serialization checks model arithmetic and the supported target mapping. Identical models and options produce identical UTF-8 bytes. Use OfficeIMO.Invoicing.Validation to check the resulting bytes against an explicit XSD and Schematron release. Successful serialization alone does not establish standards compliance.

Supported authoring contract

Area Supported data
Syntax and profiles Factur-X 1.09.2 / ZUGFeRD 2.5.2 CII D22B with MINIMUM, BASIC WL, BASIC, EN 16931 and EXTENDED; EN 16931 1.3.16 and XRechnung 3.0.2 in CII D16B or UBL 2.1; Peppol BIS Billing 3.0.21 in UBL 2.1
Documents Invoice (380), credit note (381), partial invoice (326), corrected invoice (384), prepayment invoice (386) and self-billed invoice (389); document currency and accounting-currency VAT. UBL credit notes cannot carry a due date or project reference; writing or converting those fields reports unsupported target data. Peppol BIS Billing rejects self-billed invoices because they require a separate self-billing contract.
Parties Seller, buyer, payee, tax representative, addresses, identifiers and contacts within each semantic role. Tax registrations retain their identifier and arbitrary source scheme. Target inspection reports the exact indexed registration when a target permits only VAT, one seller fiscal registration, or a canonical CII VA/FC scheme.
Lines Quantities, price base quantities, net/gross prices, discounts, allowances, charges, item identifiers, classifications and attributes
VAT and totals Category/rate breakdowns, exemptions, document adjustments, prepayments and payable rounding
Payments Ordered payment-means occurrences with their own description, account, reference, direct-debit and masked-card data. Independent PaymentReference, CreditorIdentifier and DirectDebitMandateReference retain invoice-level data when no payment means is declared. UBL requires a payment instruction for a remittance reference or mandate; conversion reports those fields rather than inventing a means code. UBL preserves card network identifiers; CII reports them as unsupported. Conflicting invoice-level and occurrence values are reported by exact payment index.
References Orders, preceding invoices, contracts, projects, delivery, periods, accounting and supporting documents. CII preserves a sales-order-only reference; UBL reports that it requires the associated purchase-order reference. External locations preserve well-formed absolute URIs, including FTP and URN schemes, without fetching them.

IBAN classification checks the registered country prefix, national length and character structure, and MOD-97 checksum against the SWIFT IBAN Registry, release 102. Unknown prefixes and country-invalid identifiers remain generic UBL creditor accounts; they cannot be declared as CII IBANs. These checks do not establish that an account exists.

Lower Factur-X profiles intentionally carry less business data. The default RejectDataLoss projection policy reports each populated source field that the selected profile omits. AllowProfileDefinedDataLoss permits only that declared profile reduction and returns the same findings as warnings from InspectTarget. MINIMUM and BASIC WL carry calculated aggregates without XML line occurrences.

Use the constants in InvoiceDocumentTypes to select a document type. The qualified type mapping covers the following pinned contracts; required business data still depends on the selected type and profile:

Contract Syntax Qualified types
EN 16931 1.3.16 CII D16B, UBL 2.1 326, 380, 381, 384, 386, 389
XRechnung 3.0.2, 2026-08-31 rules CII D16B, UBL 2.1 326, 380, 381, 384, 386, 389
Peppol BIS Billing 3.0.21 UBL 2.1 326, 380, 381, 384, 386
Factur-X 1.09.2 / ZUGFeRD 2.5.2, all five profiles CII D22B 326, 380, 381, 384, 386, 389

A corrected invoice can identify the original through PrecedingInvoices. Selecting prepayment type 386 does not infer a paid amount; set PrepaidAmount when the business record actually includes a payment. Selecting self-billed type 389 does not change seller/buyer roles or establish permission to self-bill.

XRechnung is the only national CIUS with an authoring contract because this release includes its CII/UBL syntax mappings, pinned rules and corpus evidence. EXTENDED-CTC-FR remains recognizable for inspection but cannot be selected for authoring or validation. Peppol BIS is a cross-border network usage specification, not a substitute for a national CIUS contract.

Create Polish FA(3)

Fa3InvoiceWriter uses the shared Invoice model with explicit national options. FA(3) is a separate format contract rather than another EN profile.

var polish = new Invoice {
    Number = "FA-2026-001", IssueDate = new DateTime(2026, 9, 30), Currency = "PLN",
    Seller = new InvoiceParty {
        Name = "Example Seller",
        Address = new InvoiceAddress {
            CountryCode = "PL", Line1 = "Example Street 1", Line2 = "00-001 Warszawa"
        }
    },
    Buyer = new InvoiceParty {
        Name = "Example Buyer",
        Address = new InvoiceAddress {
            CountryCode = "PL", Line1 = "Example Street 2", Line2 = "00-001 Warszawa"
        }
    }
};
// Fictional example identities; supply the issuer's actual identifiers.
polish.Seller.TaxRegistrations.Add(
    new InvoiceTaxRegistration("9999999999", "NIP", InvoiceTaxRegistrationKind.Fiscal));
polish.Buyer.TaxRegistrations.Add(
    new InvoiceTaxRegistration("1111111111", "NIP", InvoiceTaxRegistrationKind.Fiscal));
polish.Lines.Add(new InvoiceLine {
    Id = "1", Name = "Consulting", Quantity = 1, UnitPrice = 100, UnitCode = "HUR",
    Tax = new InvoiceTaxCategory { Code = "S", Rate = 23 }
});
var national = new Fa3InvoiceWriteOptions(
    Fa3InvoiceKind.TaxInvoice,
    new DateTimeOffset(2026, 9, 30, 12, 0, 0, TimeSpan.Zero),
    new Fa3InvoiceAnnotations());
var findings = Fa3InvoiceWriter.Inspect(polish, national);
byte[] fa3Xml = Fa3InvoiceWriter.Write(polish, national);

Creation time and annotations are issuer declarations. The annotations cover cash accounting, self-billing, reverse charge, split payment, triangular transactions, an explicit exemption legal basis and margin procedures. This authoring contract declares ordinary buyer JST/GV roles and no new means of transport. It does not infer those choices from names or item descriptions.

National kind Authoring contract
VAT Ordinary PLN amounts use the shared calculator. Foreign currency or margin procedures require explicit national amounts.
KOR Common type 384, preceding invoice number and date, optional actual KSeF identifier, correction reason/timing and explicit signed national amounts. Rows express differences; previous-state row authoring is outside this contract.
ZAL Explicit national advance amounts and full order rows whose gross calculation agrees with the order total.
KOR_ZAL Explicit signed national amounts, preceding invoice reference, and Fa3Order.CorrectionDifferences(originalTotal, revisedTotal, differences, differenceTaxAmounts). Signed row amounts and explicit P_11VatZ declarations in row order reconcile the order totals. P_15ZK is optional. An unchanged order requires before/after rows and is rejected by this contract.
ROZ / KOR_ROZ Settlement or settlement-correction kind, explicit national settlement amounts and previous advance references. Corrections also identify the preceding invoice and may provide P_15ZK.
UPR Explicit national amounts; omitted simplified buyer name and invoice lines are supported.

Use Fa3FiscalAmounts and Fa3TaxSummary for national P_15 and P_13/P_14 declarations. They are not relabeled EN payable totals. Foreign-currency taxable buckets require explicit PLN tax amounts; an exchange rate is never guessed. Ordinary PLN invoices derive their amounts from the shared calculator and reject FiscalAmounts overrides. Dates, country and currency codes, NIP and contact fields are checked against the pinned schema restrictions. A NIP pattern check does not establish tax registration. Negative line formulas that require rounding need an explicit DeclaredNetAmount. EN negative-half rounding does not become a Polish fiscal calculation rule. EN prepayments, payable rounding and aggregate declarations must not be passed as substitutes for national payment or settlement records.

Invoice and order rows reuse InvoiceLine. Row identifiers are distinct positive integers, prices apply to one unit, and unsupported adjustments or item metadata block output. Known unit codes map to national labels; UnitLabels supplies literal labels for other codes. LineTaxLabels distinguishes national np I and np II when the common category is O. An override must agree with the common category and rate. The supported payment forms are cash, card, cheque and generic transfer; a SEPA-specific code is reported rather than reduced silently.

Inspect reports each unsupported populated field. Write blocks when a finding is an error and bounds output to 16 MiB. The qualified XSD cases cover all seven kinds, foreign-currency tax, exemption and margin declarations, periods and bank payments. Validation establishes structure, not Polish tax treatment or KSeF acceptance. Additional parties and JST/GV roles, new means of transport, previous-state correction rows, partial-payment histories, settlement charges, national item classifications and attachments require additional native mappings.

Read Polish FA(3)

Fa3InvoiceReader reads the Polish FA(3), schema 1-0E, variant 3 document. It retains national document kinds, creation timestamps, P_15, every P_13/P_14 VAT bucket, PLN tax declarations and literal line units. The common Invoice projection contains supported identities, addresses, contacts, dates, ordinary priced lines and payment instructions. A NIP remains a fiscal registration; it does not establish VAT registration. Address lines remain free text.

var fa3 = Fa3InvoiceReader.Read(File.ReadAllBytes("polish-invoice.xml"));
Console.WriteLine($"{fa3.Kind}: {fa3.Invoice.Number}, P_15={fa3.DeclaredTotal}");
foreach (var diagnostic in fa3.UnmappedData.Concat(fa3.CommonMappingDiagnostics))
    Console.WriteLine($"{diagnostic.Location}: {diagnostic.Message}");
byte[] original = fa3.GetOriginalBytes();

The common projection does not recalculate national amounts or infer an amount due. Corrections retain signed differences and previous-state rows; advance and settlement rows are not interpreted as ordinary billed lines. Missing simplified invoice quantities and prices remain absent in the national line data. Other national annotations, order details, correction references, settlement charges and attachments are reported as unmapped rather than discarded.

GetOriginalBytes() returns unchanged source bytes even after common-model edits. WriteCommonInvoice blocks conversion when national semantics or unmapped fields would be lost. Reading is separate from FA(3) authoring, fiscal validation and KSeF acceptance. Use the offline FA(3) schema validator to qualify exact source bytes against the official XSD.

Read and edit safely

var parsed = InvoiceParser.Read(File.ReadAllBytes("invoice.xml"));
foreach (var item in parsed.UnmappedData)
    Console.WriteLine($"{item.Location}: {item.Message}");

if (parsed.HasCompleteMapping) {
    parsed.Invoice.Lines[0].Quantity = 2m;
    InvoiceCalculator.UpdateDeclaredAmounts(parsed.Invoice);
    File.WriteAllBytes("edited.xml", parsed.Write(new InvoiceXmlOptions(
        InvoiceSpecificationRelease.FacturX_1_09_2_Zugferd_2_5_2,
        InvoiceSyntax.Cii,
        InvoiceProfile.En16931)));
}

Unknown business elements, attributes and unsupported semantic variations are reported. Rewriting blocks by default when it would discard them. The explicit allowUnmappedDataLoss option accepts the reported loss; it does not preserve unknown extensions. GetOriginalBytes() always returns the original bytes, even after model edits.

For selected header changes on a source with unmapped extensions, use the preservation editor:

var source = InvoiceSourceDocument.Load("invoice.xml");
var result = InvoiceSourceEditor.Apply(source, new InvoiceSourceEdits(
    number: "INV-002",
    issueDate: new DateTime(2026, 9, 30),
    buyerReference: "BUYER-002"));
if (result.Succeeded)
    File.WriteAllBytes("edited.xml", result.Document!.ToBytes());
foreach (var diagnostic in result.Diagnostics)
    Console.WriteLine($"{diagnostic.Location}: {diagnostic.Message}");

InvoiceSourceEdits replaces an existing number, issue date, due date, buyer reference or payment reference. Each field must have one unambiguous plaintext location. All replacements are checked before any mutation; a failed plan returns no edited document. Number changes retain payment references unless a replacement is supplied separately. Signed XML, structured or annotated fields, unsupported date representations and UBL credit-note due dates are rejected.

Unedited sources return their exact original bytes. Editing emits UTF-8 XML and retains other elements, attributes, comments, processing instructions and text, including carriage returns; prefix placement, CDATA spelling and declaration formatting can change. Input and output are bounded to 16 MiB, depth 128, 100,000 XML reader nodes and 200,000 attributes. Text replacements are limited to 4,096 characters. Dates accept existing CII format 102 or plain UBL yyyy-MM-dd. Completion establishes that the requested edits were applied, so validate the resulting business data and exact XML against the intended standards release. The shared workflows compose these checks and safe file publication.

Duplicate invoice-currency or accounting-currency VAT totals are reported as unmapped data. UBL parsing retains the first invoice-currency total that includes a VAT breakdown, keeping that group's amount and breakdown together. For CII and accounting-currency amounts, parsing retains the first total. An explicit lossy rewrite uses those retained values; the resulting model must still pass validation.

Declared source line and VAT amounts are preserved. Model checks permit up to 0.02 difference from the unrounded line formula and a conservative 0.01 VAT rounding difference for taxable categories; zero-tax categories require exactly zero VAT. Totals must match the resulting amounts exactly. These checks do not replace release-specific rules. UpdateDeclaredAmounts explicitly recalculates lines, VAT and totals after financial edits.

For aggregate-only MINIMUM or BASIC WL data, recalculation retains the available tax bases and VAT amounts and rebuilds dependent totals, including prepayment edits. It does not create missing invoice lines. Target inspection still rejects adjustments that the selected profile cannot carry, such as a MINIMUM prepayment or a lower-profile rounding adjustment.

Accounting-currency VAT needs an explicit decision after financial edits. When the invoice VAT total changes or has no retained baseline, UpdateDeclaredAmounts clears TaxAmountInAccountingCurrency and retains TaxCurrency; validation blocks writing until the amount is refreshed. An unchanged retained VAT total preserves its imported accounting-currency amount. Changing the invoice currency or an established tax currency also clears that amount. Set both currencies before supplying a refreshed amount. Supply the applicable exchange rate as accounting-currency units per invoice-currency unit to calculate that amount explicitly:

invoice.TaxCurrency = "PLN";
var edit = InvoiceEditor.Recalculate(invoice, taxExchangeRate: 4.25m);
foreach (var diagnostic in edit.Diagnostics)
    Console.WriteLine($"{diagnostic.Location}: {diagnostic.Message}");

InvoiceEditor.Recalculate(invoice) reports a required accounting-currency refresh as INV-ACCOUNTING-VAT-REFRESH. Neither API chooses a tax-point date, fetches exchange rates, nor infers a rate from historical amounts. Supply the rate required by the transaction's accounting rules.

Model validation requires a seller business, legal or VAT identifier, and an account for credit-transfer payment codes 30 and 58. VAT checks cover category-specific registration requirements, exemption reasons on the resulting breakdown, and intra-community delivery details. Imported header-only exemption reasons remain valid through recalculation. Outside-scope VAT cannot mix with other categories or carry party VAT identifiers. Official code lists and release-specific rules remain the responsibility of the optional standards validator.

Target checks require a mandate reference for direct-debit codes 49 and 59 in XRechnung and Peppol. XRechnung, and Peppol transactions where both parties are in Germany, also require creditor and debtor identifiers in the direct-debit group; code 59 cannot include transfer accounts or card details in those profiles. Base EN 16931 does not impose those additional profile requirements.

Quantity, price, base-quantity and percentage calculations retain intermediate precision until monetary rounding. Monetary results use two decimal places with ties towards positive infinity; values that exceed decimal capacity are rejected instead of silently losing cents. Caller text must contain valid XML characters. The model permits up to 4 MiB of combined UTF-8 text and 8 MiB of embedded bytes. Parsing and authoring share a 50,000-item budget across collections, including declared or calculated VAT breakdowns. Parsing rejects inputs with more than 1,000 mapping diagnostics. Model validation, target inspection and conversion return at most 999 detailed diagnostics plus a summary that retains the highest omitted severity. Diagnostic codes are bounded to 256 characters; messages and locations to 4,096, with an explicit truncation marker when needed. Serialized XML is limited to 16 MiB while it is written.

Convert CII and UBL

var conversion = InvoiceConverter.Convert(File.ReadAllBytes("invoice.xml"),
    new InvoiceXmlOptions(
        InvoiceSpecificationRelease.XRechnung_3_0_2_2026_08_31,
        InvoiceSyntax.Ubl,
        InvoiceProfile.XRechnung));
if (conversion.Succeeded)
    File.WriteAllBytes("converted.xml", conversion.Xml!);
else
    foreach (var diagnostic in conversion.Diagnostics)
        Console.WriteLine($"{diagnostic.Location}: {diagnostic.Message}");

Conversion produces no bytes if observed source data cannot be represented in the target. Examples include a tax-registration scheme the target would relabel, a sales-order-only reference when writing UBL, CII card-network metadata, and conflicting exemption reasons or singleton payment fields. Every diagnostic names the exact source-model path and unsupported target meaning. A changed guideline is reported and requires validation against the target release. This is a bounded semantic conversion, with explicit loss reporting for fields outside the supported contract.

Inspect profile declarations

using OfficeIMO.Invoicing;

var declaration = InvoiceProfileDeclaration.Read(File.ReadAllBytes("invoice.xml"));
Console.WriteLine(declaration.GuidelineId);
if (declaration.Profile is InvoiceProfile profile && profile != InvoiceProfile.PeppolBis)
    Console.WriteLine(InvoiceProfiles.GetXmpConformanceLevel(profile));

The catalogue distinguishes MINIMUM, BASIC WL, BASIC, EN 16931, EXTENDED, XRechnung 3.0, EXTENDED-CTC-FR, and Peppol BIS Billing 3.0. Unknown identifiers are returned with a null profile; missing, ambiguous, malformed, or oversized input is rejected. Peppol BIS does not define Factur-X XMP metadata.

The French profile identifier follows AFNOR XP Z12-012. Recognition does not establish French business-rule coverage.

For visible hybrid PDFs, add the optional OfficeIMO.Invoicing.Pdf adapter. The XML engine remains independent of PDF generation.

Measure equivalent workloads

OfficeIMO.Invoicing.Benchmarks measures XML read, XML write, pinned rules validation and multilingual PDF generation separately over the same deterministic 25-line invoice. Correctness checks run outside measurement, and the suite owns explicit Windows, Linux and macOS elapsed/allocation ceilings.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 is compatible.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.7.2

    • No dependencies.
  • .NETStandard 2.0

    • No dependencies.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on OfficeIMO.Invoicing:

Package Downloads
OfficeIMO.Workflows

Typed local document workflows that compose first-party OfficeIMO conversion, PDF, and provenance capabilities.

OfficeIMO.Invoicing.Validation

Pinned schema and Schematron validation for OfficeIMO electronic invoices.

OfficeIMO.Invoicing.Pdf

Optional PDF presentation and hybrid CII invoice generation for OfficeIMO.Invoicing.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.4.5 567 10/10/2026
3.4.4 152 9/27/2026
3.4.3 159 9/12/2026