Ofdrw.Net.Layout
0.1.0-preview.4
dotnet add package Ofdrw.Net.Layout --version 0.1.0-preview.4
NuGet\Install-Package Ofdrw.Net.Layout -Version 0.1.0-preview.4
<PackageReference Include="Ofdrw.Net.Layout" Version="0.1.0-preview.4" />
<PackageVersion Include="Ofdrw.Net.Layout" Version="0.1.0-preview.4" />
<PackageReference Include="Ofdrw.Net.Layout" />
paket add Ofdrw.Net.Layout --version 0.1.0-preview.4
#r "nuget: Ofdrw.Net.Layout, 0.1.0-preview.4"
#:package Ofdrw.Net.Layout@0.1.0-preview.4
#addin nuget:?package=Ofdrw.Net.Layout&version=0.1.0-preview.4&prerelease
#tool nuget:?package=Ofdrw.Net.Layout&version=0.1.0-preview.4&prerelease
Ofdrw.Net
Ofdrw.Net is a preview-stage .NET SDK and CLI for OFD document packaging, reading, editing, rendering, conversion, and signature-integrity workflows.
免责声明(请在使用前阅读)
本项目当前处于早期阶段(MVP/预览版),实现目标是为 .NET 生态提供 OFD 文档生成、读取与格式转换能力。
- 本项目并非官方标准实现,也不构成对任何国家/行业标准合规性的承诺。
- 在医疗、档案、司法、政务等高风险场景中使用前,请自行完成充分的功能验证、兼容性验证与安全评估。
- 与签名、签章、加密、长期保存、合规审计相关的能力当前仅部分实现或预留扩展点,不应默认视为满足生产要求。
- 因使用本项目造成的直接或间接损失,使用者应自行评估并承担相应风险。
Acknowledgements
- 本项目在模块划分、能力边界与目标方向上参考了原项目 ofdrw/ofdrw(OFD Reader & Writer, Java)。
- 感谢原项目为 OFD 生态提供的开源实践与 API 设计思路。本项目为
.NET生态下的独立实现,不隶属于原项目。
Capabilities
See docs/feature-parity.md for the maintained OFDRW comparison, completed hardening work, and remaining production gaps.
- OFD core models, document builder API, globally unique object IDs, layers, templates, text runs, vector paths, images, fonts, attachments, annotations, and custom tags.
- Bounded OFD ZIP loading with path traversal, entry count, expanded-size, and compression-ratio checks.
- Standard package writing with
OFD.xml, document/page/resource references, attachments, custom tags, templates, and preserved extension entries. - Loss-aware reading that keeps unknown XML nodes and package entries available for round-trip workflows.
- Text extraction, page reorder/removal/crop, and self-contained document merge helpers.
- PDF to OFD conversion by embedding rendered PDF pages as OFD image objects.
- DOCX to PDF conversion through Microsoft Word on macOS when available, with isolated LibreOffice fallback, plus DOCX to OFD by composing the PDF pipeline.
- OFD to PDF conversion with templates, layers, embedded fonts, positioned text runs, vector paths, images, crop origins, and raster fallback.
- OFD page to self-contained SVG conversion with template vectors, text, colors, transforms, and embedded images.
- OFD signature description generation through a pluggable signed-value provider.
- SM3, SHA-1, and SHA-256 protected-entry digest verification plus pluggable
SignedValue.datverification. - Command-line conversion, extraction, editing, SVG, and signature verification tools packaged as
Ofdrw.Net.Cli.
DOCX rendering prefers an installed Microsoft Word on macOS for the closest Word layout fidelity; macOS may ask the host process for Automation permission the first time. Other environments use LibreOffice: install it and make sure soffice is available on PATH, set OFDRW_LIBREOFFICE_PATH, or configure DocxConversionOptions.LibreOfficePath. The LibreOffice backend can expose additional font directories and, on macOS, references installed Microsoft Office fonts without bundling them. PDF rasterization uses pdftoppm when converting PDF pages into OFD image resources, so PDF to OFD and DOCX to OFD also require Poppler on PATH.
For Developers
Install the high-level conversion package:
dotnet add package Ofdrw.Net.Converter --version 0.1.0-preview.4
For a narrower dependency surface, install the PDF converter package directly:
dotnet add package Ofdrw.Net.Converter.Pdf --version 0.1.0-preview.4
Install DOCX conversion independently:
dotnet add package Ofdrw.Net.Converter.Docx --version 0.1.0-preview.4
Install SVG or signature support independently:
dotnet add package Ofdrw.Net.Converter.Svg --version 0.1.0-preview.4
dotnet add package Ofdrw.Net.Signatures --version 0.1.0-preview.4
Convert PDF to OFD:
using Ofdrw.Net.Converter.Pdf.Converters;
await using var input = File.OpenRead("input.pdf");
await using var output = File.Create("output.ofd");
var converter = new PdfToOfdConverter();
await converter.ConvertAsync(input, output);
Convert DOCX to PDF or OFD:
using Ofdrw.Net.Converter.Docx.Converters;
await using var docx = File.OpenRead("input.docx");
await using var pdf = File.Create("output.pdf");
await new DocxToPdfConverter().ConvertAsync(docx, pdf);
await using var secondDocx = File.OpenRead("input.docx");
await using var ofd = File.Create("output.ofd");
await new DocxToOfdConverter().ConvertAsync(secondDocx, ofd);
Both converters expose stream-based APIs. DocxToOfdConverter removes its private PDF intermediate after conversion. DocxConversionOptions.Engine selects Auto, MicrosoftWord, or LibreOffice; configure a non-default LibreOffice executable with the same options or OFDRW_LIBREOFFICE_PATH.
Convert OFD to PDF:
using Ofdrw.Net.Converter.Pdf.Converters;
await using var input = File.OpenRead("input.ofd");
await using var output = File.Create("output.pdf");
var converter = new OfdToPdfConverter();
await converter.ConvertAsync(input, output);
Convert one OFD page to SVG:
using Ofdrw.Net.Converter.Svg.Converters;
await using var input = File.OpenRead("input.ofd");
await using var output = File.Create("page-1.svg");
await new OfdToSvgConverter().ConvertAsync(input, output, pageIndex: 0);
Convert selected pages with 1-based page numbers in your application code converted to zero-based indexes:
var pages = new[] { 0, 2, 3 }; // pages 1, 3, and 4
await converter.ConvertAsync(input, output, pages);
Build an OFD document programmatically:
using Ofdrw.Net.Core.Models;
using Ofdrw.Net.Layout.Builders;
using Ofdrw.Net.Packaging;
var builder = new OfdDocumentBuilder();
builder.AddPage(new OfdPage
{
Index = 0,
WidthMillimeters = 210,
HeightMillimeters = 297,
Elements =
{
new OfdTextElement
{
Text = "Hello OFD",
FontName = "SimSun",
FontSizeMillimeters = 4,
XMillimeters = 20,
YMillimeters = 20,
WidthMillimeters = 80,
HeightMillimeters = 10
}
}
});
await using var output = File.Create("hello.ofd");
await new OfdPackageWriter().WriteAsync(builder.Build(), output);
Read an OFD package:
using Ofdrw.Net.Reader.Readers;
await using var input = File.OpenRead("input.ofd");
var package = await new OfdReader().ReadAsync(input);
Console.WriteLine(package.Pages.Count);
Extract text or edit page order:
using Ofdrw.Net.Layout.Editing;
using Ofdrw.Net.Reader.Extraction;
var text = new OfdTextExtractor().Extract(package, includeTemplates: true);
OfdDocumentEditor.ReorderPages(package, new[] { 2, 0, 1 });
OfdDocumentEditor.CropPage(package.Pages[0], x: 10, y: 10, width: 180, height: 260);
Verify signed-entry integrity:
using Ofdrw.Net.Signatures.Verification;
await using var input = File.OpenRead("signed.ofd");
var report = await new OfdSignatureVerifier().VerifyAsync(input);
Console.WriteLine(report.ReferenceIntegrityValid);
Console.WriteLine(report.FullyValid);
ReferenceIntegrityValid only means every declared protected-entry digest matched. FullyValid additionally requires an IOfdSignedValueVerifier registered for each signature method and a valid SignedValue.dat. This distinction prevents an SM3 digest check from being mistaken for full SES/SM2 electronic-seal verification.
Create a signature by implementing IOfdSignatureProvider. The provider receives the exact serialized Signature.xml bytes and the OFD property-information path, and returns the vendor/SES signed-value bytes. OfdSignatureService writes the standard signature list, protected-entry references, signature description, optional seal, and SignedValue.dat.
Package overview:
Ofdrw.Net.Converter: convenience meta-package for conversion use cases.Ofdrw.Net.Converter.Docx: Word-preferred, LibreOffice-fallback DOCX to PDF/OFD conversion.Ofdrw.Net.Converter.Pdf: PDF/OFD converter implementation.Ofdrw.Net.Converter.Svg: OFD page to SVG converter.Ofdrw.Net.Signatures: signature generation and verification extension points.Ofdrw.Net.Cli: command-line conversion and document utility tool.Ofdrw.Net.Converter.Abstractions: converter interfaces.Ofdrw.Net.Core: shared models and constants.Ofdrw.Net.Packaging: OFD package writer and archive utilities.Ofdrw.Net.Reader: OFD package reader.Ofdrw.Net.Layout: document builder helpers.
For CLI Users
Install the CLI as a .NET tool:
dotnet tool install --global Ofdrw.Net.Cli --version 0.1.0-preview.4
Convert by file extension:
ofdrw convert input.pdf output.ofd
ofdrw convert input.ofd output.pdf
ofdrw convert input.docx output.pdf
ofdrw convert input.docx output.ofd
Specify the conversion direction explicitly:
ofdrw pdf-to-ofd --input input.pdf --output output.ofd
ofdrw ofd-to-pdf --input input.ofd --output output.pdf
ofdrw docx-to-pdf --input input.docx --output output.pdf
ofdrw docx-to-ofd --input input.docx --output output.ofd
ofdrw ofd-to-svg --input input.ofd --output page-1.svg --pages 1
Select a DOCX renderer or provide fonts for the LibreOffice backend:
ofdrw docx-to-pdf input.docx output.pdf --docx-engine word
ofdrw docx-to-ofd input.docx output.ofd --docx-engine libreoffice --font-directory /path/to/fonts
Convert selected pages:
ofdrw pdf-to-ofd -i input.pdf -o selected.ofd --pages 1,3-5
ofdrw ofd-to-pdf -i input.ofd -o selected.pdf --pages 2
Extract text and edit documents:
ofdrw extract-text input.ofd output.txt --include-templates
ofdrw reorder input.ofd reordered.ofd --pages 3,1,2
ofdrw merge merged.ofd first.ofd second.ofd
Verify signatures:
ofdrw verify-signatures --input signed.ofd
The signature command exits with 0 for full verification, 2 when protected-entry integrity passes but the signed-value algorithm has no registered verifier, and 3 for invalid or incomplete signatures.
Show help:
ofdrw --help
Run the CLI from a source checkout:
dotnet run --project src/Ofdrw.Net.Cli/Ofdrw.Net.Cli.csproj -- convert input.pdf output.ofd
Build a standalone executable from source:
dotnet publish src/Ofdrw.Net.Cli/Ofdrw.Net.Cli.csproj -c Release -o artifacts/ofdrw-cli
./artifacts/ofdrw-cli/Ofdrw.Net.Cli convert input.pdf output.ofd
Repository Layout
src/Ofdrw.Net.Coresrc/Ofdrw.Net.Packagingsrc/Ofdrw.Net.Layoutsrc/Ofdrw.Net.Readersrc/Ofdrw.Net.Converter.Abstractionssrc/Ofdrw.Net.Converter.Docxsrc/Ofdrw.Net.Converter.Pdfsrc/Ofdrw.Net.Converter.Svgsrc/Ofdrw.Net.Signaturessrc/Ofdrw.Net.Convertersrc/Ofdrw.Net.Clitestse2e/Ofdrw.Net.Converter.Pdf.E2E
Development
Restore, build, and test:
dotnet restore Ofdrw.Net.sln
dotnet build Ofdrw.Net.sln
dotnet test Ofdrw.Net.sln
Pack locally:
dotnet pack Ofdrw.Net.sln -c Release -o artifacts/nuget
Run the package-consumer E2E check:
scripts/run-converter-package-e2e.sh
Use a specific local package version for E2E:
scripts/run-converter-package-e2e.sh 0.1.0-preview.local
Notes
- SDK libraries target
netstandard2.0andnetstandard2.1. - The CLI targets
net10.0. - Existing source XML is preserved for high-fidelity round trips. Clear an element's
SourceXmlbefore expecting all typed property changes to be serialized. - Merge produces a self-contained typed document, flattens referenced templates, and rejects unknown raw objects unless
SkipUnsupportedRawElementsis explicitly enabled. - SM3 reference digests are built in. SES/SM2 electronic-seal verification must be supplied through
IOfdSignedValueVerifier. - GM/T 0099 encrypted-envelope processing and long-term archival validation are not built in.
OfdCryptographicCapabilitiesexposes these support boundaries to applications. - A repository license has not yet been selected by the project owner. The NuGet workflow now blocks publication until both a license file and NuGet license metadata exist. Direct dependency declarations are recorded in
THIRD-PARTY-NOTICES.md.
| Product | Versions 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 was computed. 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 was computed. 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 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. 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. |
-
.NETStandard 2.0
- Ofdrw.Net.Core (>= 0.1.0-preview.4)
-
.NETStandard 2.1
- Ofdrw.Net.Core (>= 0.1.0-preview.4)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Ofdrw.Net.Layout:
| Package | Downloads |
|---|---|
|
Ofdrw.Net.Converter.Pdf
PDF <-> OFD conversion implementation for Ofdrw.Net. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-preview.4 | 58 | 7/22/2026 |
| 0.1.0-preview.3 | 54 | 7/18/2026 |
| 0.1.0-preview.2 | 62 | 7/18/2026 |