Net4x.PdfExporterLib
2.0.0.26253
dotnet add package Net4x.PdfExporterLib --version 2.0.0.26253
NuGet\Install-Package Net4x.PdfExporterLib -Version 2.0.0.26253
<PackageReference Include="Net4x.PdfExporterLib" Version="2.0.0.26253" />
<PackageVersion Include="Net4x.PdfExporterLib" Version="2.0.0.26253" />
<PackageReference Include="Net4x.PdfExporterLib" />
paket add Net4x.PdfExporterLib --version 2.0.0.26253
#r "nuget: Net4x.PdfExporterLib, 2.0.0.26253"
#:package Net4x.PdfExporterLib@2.0.0.26253
#addin nuget:?package=Net4x.PdfExporterLib&version=2.0.0.26253
#tool nuget:?package=Net4x.PdfExporterLib&version=2.0.0.26253
PdfExporterLib
WPF building blocks for a PDF viewer/exporter application — Esportazione di pdf in altri formati.
The package provides a reusable Window base class that hosts the
PdfViewerLibrary control inside WPF, a
secondary window for reviewing extracted text and tabular data, and a small set of data utilities
(CSV export, batch file renaming, visual-tree lookup, case-insensitive string replacement).
| Package id | Net4x.PdfExporterLib |
| Target framework | net452 (Windows only — WPF + Windows Forms interop) |
| License | Apache-2.0 |
Installation
<PackageReference Include="Net4x.PdfExporterLib" Version="2.0.0.*" />
dotnet add package Net4x.PdfExporterLib
The consuming project must be a Windows desktop project that references PresentationCore,
PresentationFramework, WindowsBase, System.Windows.Forms and WindowsFormsIntegration.
What is in the package
| Type | Purpose |
|---|---|
PdfExporterLib.MainPdfWindow |
Window base class hosting a PdfViewerControl, with tray icon, open/export commands and batch folder processing |
PdfExporterLib.NotepadWindow |
Ready-made window with a text editor and a hosted DataGridView |
PdfExporterLib.ControlFinder |
Visual-tree lookup by type and name |
PdfExporterLib.DataUtility.CsvTableExporter |
Writes a DataTable as delimited or fixed-width text |
PdfExporterLib.DataUtility.FileRenamer |
Sequential renaming of a batch of files |
PdfExporterLib.DataUtility.StringExtension |
ReplaceCaseInsensitive extension method |
Hosting the PDF viewer
MainPdfWindow ships without markup of its own: derive your window from it and wire your XAML to
the protected handlers it already implements.
<pdf:MainPdfWindow x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:pdf="clr-namespace:PdfExporterLib;assembly=PdfExporterLib"
Title="PDF Exporter" Height="720" Width="1024"
AllowDrop="True"
Loaded="Window_Loaded" Drop="Window_Drop"
Closing="Window_Closing" StateChanged="Window_StateChanged">
<Grid x:Name="ContentGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Menu Grid.Row="0">
<MenuItem Header="File">
<MenuItem Header="Apri..." Click="OpenMenu_Click" />
<MenuItem Header="Esci" Click="ExitMenu_Click" />
</MenuItem>
<MenuItem Header="?">
<MenuItem Header="Informazioni su..." Click="AboutMenu_Click" />
</MenuItem>
</Menu>
</Grid>
</pdf:MainPdfWindow>
using PdfExporterLib;
using PdfViewerLibrary.Model;
public partial class MainWindow : MainPdfWindow
{
public MainWindow()
{
InitializeComponent();
// Adds a WindowsFormsHost carrying the PdfViewerControl to row 1 of the grid.
// Pass null for the grid to let ControlFinder locate the first Grid in the window.
LoadWfUserControl(ContentGrid);
}
protected override void OnPdfViewerControlPdfOpened(object sender, FileNameEventArgs e)
{
base.OnPdfViewerControlPdfOpened(sender, e); // publishes MainPdfWindow.FileName
Title = "PDF Exporter — " + MainPdfWindow.FileName;
}
}
LoadWfUserControl(grid, printVisible, showOnlyFirstTab) gives control over the viewer chrome:
printVisible: false hides the print command, showOnlyFirstTab: true collapses the viewer down to
its first tab page.
Static helpers
MainPdfWindow.FileName; // last PDF opened by the viewer
MainPdfWindow.Unminimize(window); // restore a minimised window (no-op if not shown)
MainPdfWindow.GetTempFilePathWithExtension(".pdf"); // %TEMP%\<guid>.pdf
MainPdfWindow.GetTempFilePathWithoutExtension(); // %TEMP%\<guid>
Tray icon
The MainPdfWindow constructor installs a NotifyIcon with a Mostra / Nascondi / Esci context
menu and shows it immediately. Minimising the window hides it to the tray; the Window_Closing
handler removes the icon again, so wire your window's Closing event to it or the icon will
outlive the window.
Batch folder processing
DoOpenFolder prompts for a folder, walks every *.pdf in it, opens and closes each document, and
finally reports how many files were processed. The callback you pass is invoked once per file,
before that file is opened, so the export destination can be prepared:
private void OpenFolderMenu_Click(object sender, RoutedEventArgs e)
{
DoOpenFolder(PrepareAutomaticExport);
}
private void PrepareAutomaticExport()
{
// Called once per PDF, just before it is opened.
}
Renaming before and after processing is driven by the application settings described below.
CsvTableExporter
using (var writer = new StreamWriter(path, false, Encoding.UTF8))
{
CsvTableExporter.ExportDatatableToStream(writer, dataTable);
}
// or straight to a path
CsvTableExporter.ExportDatatableToStream(path, dataTable);
// fixed-width output, no header, no separators
CsvTableExporter.ExportDatatableToStream(
putColumnNames: false,
putColumnSeparators: false,
columnLengths: new[] { 10, 30, 8 },
outputFileStream: writer,
dataReader: dataTable);
Behaviour worth knowing before you wire it up:
- The separator is
Thread.CurrentThread.CurrentCulture.TextInfo.ListSeparator—;underit-IT,,under the invariant culture. Pin the culture if the output has to be stable. - A separator is written after every column, including the last, so each row ends with a trailing delimiter.
columnLengthspads short values with spaces and truncates long ones. Columns beyond the end of the array are written unpadded.- The method closes the
TextWriterit is given — do not reuse the writer afterwards. nullandDBNullcells become empty fields. Combining them withcolumnLengthsis not supported.- The path overload opens the file without truncating it; delete an existing file first if it may be longer than the new content.
FileRenamer
var files = Directory.GetFiles(folder, "*.pdf");
var offset = 0;
for (var i = 0; i < files.Length; i++)
FileRenamer.RenameFile(ref i, files, ref offset, "Processed_", "pdf", dontRenameFile: false);
// zeta.pdf, alpha.pdf, mu.pdf -> Processed_1.pdf, Processed_2.pdf, Processed_3.pdf
The new name is {prefix}{index + offset + 1}.{extension}, in the source file's own directory.
With dontRenameFile: true the original file name is kept and only the prefix and extension are
applied. When the computed name equals the current one the file is left untouched. The return value
is the full path of the file after the call.
The target name must not already exist: the collision branch does not recompute the candidate name and will not terminate. Rename into a clean prefix/extension pair, or check for existing targets before calling.
ControlFinder
var grid = ControlFinder.FindChild<Grid>(this, null); // first Grid in the visual tree
var editor = ControlFinder.FindChild<TextBox>(this, "Notes"); // first TextBox named "Notes"
Returns null when parent is null or nothing matches. Name matching is case sensitive. The
search does not descend into a child that already matches T but carries a different name, so a
same-typed ancestor will hide the element you are looking for.
StringExtension
using PdfExporterLib.DataUtility;
"Hello World".ReplaceCaseInsensitive("WORLD", "Earth"); // "Hello Earth"
The search term is matched literally (regex metacharacters are escaped) and $ in the replacement
is not treated as a substitution group.
NotepadWindow
var notepad = new NotepadWindow { Text = extractedText };
notepad.DataGridView.DataSource = table; // hosted System.Windows.Forms.DataGridView
if (notepad.ShowDialog() == true && notepad.TextModified)
Save(notepad.Text);
TextModified only becomes true for changes made while the window is visible, so pre-filling
Text before showing it is not reported as a user edit.
Application settings
Batch renaming in DoOpenFolder reads the PdfExporterLib.Properties.Settings application-scoped
settings. Override them in the host application's App.config:
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="PdfExporterLib.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<PdfExporterLib.Properties.Settings>
<setting name="RenameBeforeProcess" serializeAs="String"><value>False</value></setting>
<setting name="BeforePrefix" serializeAs="String"><value>Processed_</value></setting>
<setting name="BeforeExtension" serializeAs="String"><value>pdf</value></setting>
<setting name="RanameFileNameBefore" serializeAs="String"><value>False</value></setting>
<setting name="RenameAfterProcess" serializeAs="String"><value>True</value></setting>
<setting name="AfterPrefix" serializeAs="String"><value /></setting>
<setting name="AfterExtension" serializeAs="String"><value>processedPdf</value></setting>
<setting name="RanameFileNameAfter" serializeAs="String"><value>False</value></setting>
</PdfExporterLib.Properties.Settings>
</applicationSettings>
| Setting | Default | Meaning |
|---|---|---|
RenameBeforeProcess |
False |
Rename every file in the folder before processing starts |
BeforePrefix / BeforeExtension |
Processed_ / pdf |
Naming applied by the pre-processing pass |
RanameFileNameBefore |
False |
True renumbers the files, False keeps their original names |
RenameAfterProcess |
True |
Rename each file once it has been processed |
AfterPrefix / AfterExtension |
(empty) / processedPdf |
Naming applied by the post-processing pass |
RanameFileNameAfter |
False |
True renumbers the files, False keeps their original names |
The setting names RanameFileNameBefore / RanameFileNameAfter are spelled as shown — the typo is
part of the persisted configuration contract.
Dependencies
- Net4x.PdfViewerLibrary — the hosted PDF viewer control
- Net4x.InputBoxLibrary.WinForms — dialogs and shared resources
- Net4x.DataAccessLibrary.Data.Classes —
DbConvert, used by the CSV exporter - Net4x.Microsoft-WindowsAPICodePack-Core and -Shell — shell dialogs and property system
- AboutBox — the about window shown by
AboutMenu_Click
Localisation
The built-in user interface strings (tray menu, window titles, about text, progress message) are in Italian. Override the protected handlers if you need another language.
Links
Copyright © Piero Viano 2016. Released under the Apache-2.0 license.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET Framework | net452 is compatible. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
-
.NETFramework 4.5.2
- AboutBox (>= 2.0.0)
- Net4x.DataAccessLibrary.Data.Classes (>= 2.3.0.26253)
- Net4x.InputBoxLibrary.WinForms (>= 2.0.0.26250)
- Net4x.Microsoft-WindowsAPICodePack-Core (>= 1.2.0.26253)
- Net4x.Microsoft-WindowsAPICodePack-Shell (>= 1.2.0.26253)
- Net4x.PdfViewerLibrary (>= 2.2.0.26253)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0.26253 | 81 | 9/10/2026 |