PDF4me .NET SDK: C# PDF Bibliothèque et API Client
Pdf4me.Client est un .NET bibliothèque cliente pour la PDF4me API qui expose 106 actions de document sous forme de méthodes asynchrones typées. Installez-le depuis NuGet, créez-en un Pdf4meClient avec votre API clé, et convertir, optimiser, fusionner, diviser, OCR ou extraire des documents dans C# sans fournir de moteur de rendu.
Informations sur l'emballage
| Champ | Valeur |
|---|---|
| Nom du paquet | Pdf4me.Client |
| Version actuelle | 2.0.0 (Dernière mise à jour : 13/10/2026) |
| Licence | MIT |
| .NET soutien | .NET 8, 9 et 10, plus .NET Norme 2.0 pour .NET Framework 4.6.2 et versions ultérieures |
| Nombre total de téléchargements | 246,4K toutes versions confondues |
| Taille de l'emballage | 1,34 Mo |
| Actes | 106 répartis sur 18 sections |
| Dépendances d'exécution | Microsoft.Kiota.Bundle (>= 2.1.2) et Microsoft.Extensions.Logging.Abstractions (>= 8.0.3) |
| Base URL | https://api.pdf4me.com |
| Source | github.com/pdf4me/pdf4me-clientapi-dotnet |
| NuGet | nuget.org/packages/Pdf4me.Client |
Prérequis
- .NET 8 ou plus récent, ou .NET Framework 4.6.2 ou version ultérieure .NET Norme 2.0.
- UN PDF4me compte et API clé.
Installer
- dotnet CLI
- Package Manager
- PackageReference
dotnet add package Pdf4me.Client
NuGet\Install-Package Pdf4me.Client -Version 2.0.0
<PackageReference Include="Pdf4me.Client" Version="2.0.0" />
Authentifier
Configurez votre API clé dans l'environnement :
- Bash / Zsh
- PowerShell
- Windows CMD
export PDF4ME_API_KEY="your-api-key"
$env:PDF4ME_API_KEY = "your-api-key"
set PDF4ME_API_KEY=your-api-key
Sous Windows, set ne dure que pour le courant CMD session. Utiliser setx PDF4ME_API_KEY "your-api-key" Pour une valeur qui persiste après un redémarrage, ouvrez un nouveau terminal afin que le processus la prenne en compte.
Le client récupère la clé dans son constructeur. Aucun élément consigné ne contient la clé. API Une clé ou le contenu d'un document, et une clé vide ou ne contenant que des espaces, génère une erreur. ArgumentException avant qu'une quelconque requête ne soit envoyée.
Démarrage rapide
Ce programme télécharge input.pdf pour l'optimisation et enregistre le résultat sous optimized.pdf:
using Pdf4me.Client;
var apiKey = Environment.GetEnvironmentVariable("PDF4ME_API_KEY")
?? throw new InvalidOperationException("Set PDF4ME_API_KEY first.");
using var client = new Pdf4meClient(apiKey);
var result = await client.OptimizeAsync(
File.ReadAllBytes("input.pdf"), docName: "input.pdf", profile: OptimizeProfile.Max);
File.WriteAllBytes("optimized.pdf", result);
Créez un client unique et réutilisez-le pour chaque appel. Il conserve une connexion partagée, donc un client par appel négociera la connexion. TLS à chaque fois. Jetez-le une fois que vous avez terminé.
Qu'est-ce que le SDK .NET de PDF4me ?
Il s'agit d'un seul NuGet emballer, Pdf4me.Client, qui enveloppe le PDF4me API v2 derrière une seule classe. Chaque action est une méthode asynchrone sur Pdf4meClient nommé d'après son point d'extrémité, donc /api/v2/ConvertOcrPdf est ConvertOcrPdfAsyncLes premiers paramètres indiquent sur quoi l'action agit, et tous les autres sont facultatifs ; il faut donc les passer par leur nom :
var searchable = await client.ConvertOcrPdfAsync(
scan, language: "English", qualityType: QualityType.Draft);
var numbered = await client.AddPageNumberAsync(
pdf, pageNumberFormat: "Page # of {1}", alignX: AddPageNumberAlignX.Center);
Le Generated L'arbre à l'intérieur du paquet est produit par Microsoft Kiota de la PDF4me OpenAPI description, c'est pourquoi les modèles d'options et de résultats sont cohérents avec la description REST API et avec le Python et JavaScript clients : mêmes actions, mêmes noms et valeurs par défaut.
En quoi une bibliothèque PDF C# diffère-t-elle d'un client API ?
La plupart des résultats pour «c# pdf Les « bibliothèques » sont des bibliothèques de rendu auto-hébergées : vous ajoutez le package, il effectue le travail dans votre processus et vous êtes propriétaire du moteur de rendu. Pdf4me.Client est l'autre forme. Elle envoie le document à PDF4me et renvoie les octets finaux. L'échange est réel dans les deux sens, il est donc important d'être clair à ce sujet :
| Bibliothèque locale vs bibliothèque hébergée API | Bibliothèque auto-hébergée | Pdf4me.Client |
|---|---|---|
| Là où le travail se déroule | Dans votre processus | Sur le PDF4me service |
| Réseau requis | Non | Oui, chaque appel |
| Forme de coût | Licence du package, parfois par développeur ou par déploiement | MIT client, API crédits sur un forfait gratuit ou payant |
| Fonctionne hors ligne ou isolé du réseau. | Oui | Non |
| Les documents quittent votre infrastructure | Non | Oui |
| OCR, AI extraction, ZUGFeRD | Généralement un produit distinct, s'il est disponible | Ces 106 actions font partie des mêmes actions. |
| Vous maintenez | Le moteur, ses polices et ses CVEs | Un API clé |
Choisissez une bibliothèque locale lorsque les documents ne peuvent pas quitter votre réseau, lorsque vous devez travailler hors ligne ou lorsque le coût par document, compte tenu de votre volume, est plus avantageux qu'un abonnement. Optez pour ce client si vous deviez autrement intégrer plusieurs produits pour gérer la conversion. OCR, les codes-barres, la facturation électronique et AI extraction, et vous préféreriez ne pas du tout déployer ou corriger un moteur de rendu.
Notez que les deux questions les plus fréquemment posées par la fonction de saisie automatique concernant cette catégorie reçoivent ici des réponses différentes. Le client lui-même est MIT sous licence et open sourceLes cases « gratuit » et « open source » sont donc cochées pour le code que vous utilisez. Le traitement sous-jacent est assuré par un service hébergé, dont l'accès est payant au-delà de la version gratuite.
Transmission des documents et lecture des résultats
Documents zone DocumentSource: soit les octets du fichier, soit une chaîne de caractères API se va lui-même, ce qui peut être un pdf4meblobid://<id> référence blob ou un https URLLes deux conversions sont implicites ; on peut donc les passer directement. Une chaîne de caractères n’est jamais interprétée comme un chemin de fichier local ; il faut donc lire le fichier et passer ses octets.
byte[] fromBytes = await client.OptimizeAsync(File.ReadAllBytes("report.pdf"));
byte[] fromUrl = await client.OptimizeAsync("https://example.com/report.pdf");
byte[] fromBlob = await client.OptimizeAsync("pdf4meblobid://<id>");
Résultats ils reviennent de deux manières. Les actions qui produisent un document renvoient son byte[], donc File.WriteAllBytes Elle le prend directement. Les actions qui répondent avec des données renvoient plutôt un modèle typé :
DocMetadata metadata = await client.GetPdfMetadataAsync(pdf);
Console.WriteLine($"{metadata.PageCount} pages, PDF {metadata.PdfVersion}");
ReadBarcodesRes scan = await client.ReadBarcodesAsync(pdf);
foreach (var barcode in scan.Barcodes ?? [])
Console.WriteLine($"page {barcode.Page}: {barcode.Value}");
Le AI L'analyseur de documents détermine lui-même la forme de sa réponse, de sorte que tout ce qu'il renvoie arrive dans le modèle. AdditionalData:
var parsed = await client.AiDocumentParserAsync(File.ReadAllBytes("invoice.pdf"), "invoice parser");
foreach (var (field, value) in parsed.AdditionalData)
Console.WriteLine($"{field}: {value}");
Plusieurs documents fusionner dans l'ordre indiqué, et certaines actions ne nécessitent aucun document car l'entrée est du texte ou un URL:
byte[] merged = await client.MergeAsync([File.ReadAllBytes("a.pdf"), File.ReadAllBytes("b.pdf")]);
byte[] qrCode = await client.CreateBarcodeAsync("https://pdf4me.com", barcodeType: CreateBarcodeBarcodeType.QRCode);
byte[] webPage = await client.ConvertUrlToPdfAsync("https://example.com");
Options qui sont des objets, tel que ConvertToPdfAction et ImageAction, et tous les modèles de résultats, résident dans Pdf4me.Client.Generated.ModelsLes énumérations et les actions qu'elles effectuent ont des noms courts dans Pdf4me.Client (QualityType, AlignX, SplitAction), tandis que les quelques-uns dont le nom généré est déjà court (DocType, ImageTypeExtractsont utilisés directement à partir de l'espace de noms généré :
using Pdf4me.Client;
using Pdf4me.Client.Generated.Models;
var pages = await client.CreateImagesAsync(
pdf, new ImageAction { ImageExtension = ImageExtension.Png }, pageNrs: "1");
Chaque action implique également des conséquences. trois arguments optionnels : extra, un dictionnaire de champs de requête supplémentaires pour les options API La description ne les liste pas encore, elles sont envoyées telles quelles avec celles de l'action ; maxWait, ce qui limite le temps d'attente pour la tâche mise en file d'attente pour cet appel ; et cancellationToken, ce qui annule la requête et toute interrogation.
Configuration du client
using var client = new Pdf4meClient(apiKey, new Pdf4meClientOptions
{
BaseUrl = Pdf4meClient.DefaultBaseUrl, // https://api.pdf4me.com
Timeout = TimeSpan.FromSeconds(100), // each HTTP request
MaxWait = TimeSpan.FromMinutes(5), // waiting for one queued job
Logger = loggerFactory.CreateLogger<Pdf4meClient>(),
});
Dans ASP.NET Pour Core, ou toute application utilisant l'injection de dépendances, enregistrez un seul client pour l'ensemble de l'application et laissez le système de journalisation provenir de la configuration de journalisation propre à l'application :
builder.Services.AddSingleton(services => new Pdf4meClient(
builder.Configuration["Pdf4me:ApiKey"]!,
new Pdf4meClientOptions { Logger = services.GetRequiredService<ILogger<Pdf4meClient>>() }));
Donnez au client un ILogger depuis Microsoft.Extensions.Logging pour voir chaque requête, réponse, tâche en file d'attente et sondage à Debug niveau.
Comment gérer les tâches longues et la reconnaissance optique de caractères (OCR) en C# ?
Chaque action est soumise comme une tâche asynchrone. Un appel renvoie le résultat final, que le serveur ait répondu immédiatement ou mis la tâche en file d'attente, en interrogeant le serveur à l'intervalle suggéré. Ceci est important pour deux raisons : une seule await peut bloquer pendant des minutes, et ce qui met fin à l'attente est MaxWait, pas Timeout.
Timeouts'applique à chaque HTTP demande.MaxWaits'applique à l'ensemble du travail en attente, etmaxWait:une action la remplace pour cet appel.- Le OCR actions,
ConvertOcrPdfAsyncetImageExtractTextAsync, attendez au moins 10 minutes (DefaultOcrMaxWait), ou plus longtemps lorsqueMaxWaitest plus élevé.
using var cancel = new CancellationTokenSource(TimeSpan.FromMinutes(20));
byte[] searchable = await client.ConvertOcrPdfAsync(
File.ReadAllBytes("scan.pdf"), language: "English",
maxWait: TimeSpan.FromMinutes(20), cancellationToken: cancel.Token);
Erreurs
Une requête refusée ou ayant échoué génère une exception Pdf4meException, depuis Pdf4me.Client.Generated.Models:
| Propriété | Détente |
|---|---|
Message | Le APIle message de , sinon le corps de la réponse est limité à 500 caractères, sinon le HTTP statut |
ResponseStatusCode | Le HTTP code d'état |
TraceId | Le APIIdentifiant de trace de 's. Veuillez le citer lors du signalement d'un problème. |
ResponseBody | L'intégralité du corps de la réponse tel qu'envoyé |
ResponseHeaders | Les en-têtes de réponse |
Une tâche toujours en cours lorsque le délai d'attente expire TimeoutExceptionLes arguments invalides, tels qu'un document vide, lèvent une exception. ArgumentException avant l'envoi de toute requête.
try
{
byte[] result = await client.OptimizeAsync(pdf);
}
catch (Pdf4meException e)
{
Console.Error.WriteLine($"PDF4me returned {e.ResponseStatusCode}: {e.Message} (trace {e.TraceId})");
}
catch (TimeoutException e)
{
Console.Error.WriteLine(e.Message);
}
Les 18 sections et les 106 actions
Les actions sont regroupées par sections de PDF4me REST API référenceLes méthodes de chaque section résident dans leur propre fichier source. Certaines se trouvent dans une section dont le nom ne le laisse pas forcément deviner : OCR se trouve dans Rechercher, PDF/A La création se trouve dans Convertir, et MergeV3Async est dans PDF plutôt que Fusionner et scinder.
| Section | Actes | Méthodes sur Pdf4meClient |
|---|---|---|
| AI Extraction de documents | 14 | AiDocumentParserAsync, ProcessBankChequeAsync, ProcessBankStatementAsync, ProcessContractAsync, ProcessCreditCardAsync, ProcessHealthCardAsync, ProcessInvoiceAsync, ProcessMarriageCertificateAsync, ProcessMortgageDocumentAsync, ProcessOrderAsync, ProcessPayStubAsync, ProcessReceiptAsync, ProcessShippingLabelAsync, ProcessTaxDocumentAsync |
| code-barres | 7 | AddBarcodeAsync, CreateBarcodeAsync, CreateSwissQrBillAsync, ReadBarcodesAsync, ReadSwissQrBillAsync, CreateEpcQrCodeAsync, ReadBarcodesFromImageAsync |
| Convertir | 13 | ConvertHtmlToPdfAsync, ConvertJsonToExcelAsync, ConvertMdToPdfAsync, ConvertPdfToExcelAsync, ConvertPdfToPowerpointAsync, ConvertPdfToWordAsync, ConvertToPdfAsync, ConvertUrlToPdfAsync, ConvertVisioAsync, ConvertWordToPdfFormAsync, CreatePdfAAsync, FlattenPdfAsync, LinearizePdfAsync |
| Modifier | 7 | AddAttachmentToPdfAsync, AddHtmlHeaderFooterAsync, ImageStampAsync, AddMarginAsync, AddPageNumberAsync, StampAsync, SignPdfAsync |
| Exceller | 1 | FindAndReplaceTextInExcelAsync |
| Extrait | 8 | ClassifyDocumentAsync, ExtractAttachmentFromPdfAsync, ExtractPdfFormDataAsync, ExtractResourcesAsync, ExtractTableFromPdfAsync, ExtractTextByExpressionAsync, ExtractTextFromWordAsync, ParseDocumentAsync |
| Rechercher | 2 | FindAndReplaceAsync, ConvertOcrPdfAsync |
| Formulaires | 2 | AddFormFieldAsync, FillPdfFormAsync |
| Générer | 6 | EnableTrackingChangesInWordAsync, GenerateDocumentSingleAsync, GenerateDocumentMultipleAsync, GetTrackingChangesInWordAsync, ReplaceTextWithImageInWordAsync, GenerateDocumentSingleV2Async |
| Image | 13 | AddImageWatermarkToImageAsync, AddTextWatermarkToImageAsync, CompressImageAsync, ConvertImageFormatAsync, CreateImagesAsync, CropImageAsync, FlipImageAsync, GetImageMetadataAsync, ImageExtractTextAsync, RemoveExifTagsFromImageAsync, ResizeImageAsync, RotateImageAsync, RotateImageByExifDataAsync |
| Fusionner et diviser | 5 | MergeAsync, MergeOverlayAsync, SplitPdfAsync, SplitPdfByBarcodeAsync, SplitByTextAsync |
| Optimiser | 1 | OptimizeAsync |
| Organiser | 5 | DeleteBlankPagesAsync, DeletePagesAsync, ExtractPagesAsync, RotateAsync, RotatePageAsync |
| 16 | MergeV3Async, GetPdfMetadataAsync, RepairPdfAsync, CreateHyperlinkAnnotationAsync, DeleteHyperlinkAnnotationAsync, DigitalSignPdfAsync, ExtractHyperlinkAnnotationAsync, GetDocumentByTextAsync, GetTextAndCoordinatesAsync, GetTextByPositionAsync, HighlightTextAsync, PrepareForPrintAsync, ReplaceTextWithImageAsync, ResizePdfAsync, SetPdfMetadataAsync, SignDocumentAsync | |
| PDF4me | 1 | UpdateHyperlinkAnnotationAsync |
| Sécurité | 2 | ProtectAsync, UnlockAsync |
| Mot | 2 | DisableTrackingChangesInWordAsync, FindAndReplaceTextInWordAsync |
| ZUGFeRD | 1 | CreateZugferdInvoiceAsync |
Pour connaître les paramètres et la forme de la réponse de chaque action, voir la section suivante : PDF4me REST API référence, ou survolez la méthode dans votre éditeur : chaque méthode comporte un résumé de documentation qui correspond à sa page de documentation.
Migration depuis la version 1.x
La version 2.0 est une réécriture de PDF4me API La version 2 et aucune version 1.x ne fonctionnent. Le titre change :
- Il parle à API v2. 1.x appelait les points de terminaison v1 tels que
/Optimize/OptimizeByProfile; 2.0 appels/api/v2/.... - Les clients individuels et les clients par zone géographique ont disparu.
Pdf4me.Instance.Init(token)etPdf4me.Instance.OptimizeClientdevenir unnew Pdf4meClient(apiKey)chaque action étant une méthode sur celle-ci. - L'espace de noms est
Pdf4me.Client, pasPdf4meClient. - Newtonsoft.Json n'est plus une dépendanceet la version 12.0.3 vulnérable que la version 1.x a intégrée va de pair avec elle.
- Les erreurs constituent un type d'erreur.
Pdf4meApiExceptionetPdf4meBackendExceptiondevenirPdf4meException. - .NET Les versions 4.5.2 et 4.6.1 du framework ne sont plus prises en charge. La version minimale est 4.6.2, jusqu'à .NET Norme 2.0.
| 1.x | 2.0 |
|---|---|
Pdf4me.Instance.Init(token) | using var client = new Pdf4meClient(apiKey); |
OptimizeClient.OptimizeByProfileAsync(file, profile) | client.OptimizeAsync(file, profile: ...) |
MergeClient.Merge2PdfsAsync(file1, file2) | client.MergeAsync([file1, file2]) |
SplitClient.SplitByPageNrAsync(file, pageNr) | client.SplitPdfAsync(file, splitActionNumber: pageNr) |
ExtractClient.ExtractPagesAsync(file, pageNrs) | client.ExtractPagesAsync(file, pageNumbers: pageNrs) |
ConvertClient.ConvertFileToPdfAsync(file, fileName) | client.ConvertToPdfAsync(file, docName: fileName) |
PdfAClient.CreatePdfAAsync(file, compliance) | client.CreatePdfAAsync(file, compliance: ...) |
PdfAClient.RotateDocumentAsync(file, rotate) | client.RotateAsync(file, rotationType: ...) |
PdfAClient.ProtectDocumentAsync(file, password, perms) | client.ProtectAsync(file, password: ..., pdfPermission: ...) |
PdfAClient.UnlockDocumentAsync(file, password) | client.UnlockAsync(file, password: ...) |
PdfAClient.RepairDocumentAsync(file) | client.RepairPdfAsync(file) |
ImageClient.CreateThumbnailAsync(file, width, pageNr, fmt) | client.CreateImagesAsync(file, new ImageAction { ... }, pageNrs: ...) |
Ton API La clé reste la même. Remplacer using Pdf4meClient; avec using Pdf4me.Client;, ajouter using Pdf4me.Client.Generated.Models; chaque fois que vous utilisez des modèles d'options ou de résultats ou que vous effectuez une capture Pdf4meException, puis parcourez le tableau ci-dessus.
Dépannage
TimeoutException sur un document volumineux. L'emploi a survécu à l'attente, ce qui est MaxWait et par défaut à 5 minutes, pas TimeoutAbordez ce sujet lors de l'appel avec maxWait: TimeSpan.FromMinutes(20), ou sur le client pour chaque appel.
Un OCR L'appel semble bloqué pendant dix minutes. C'est le plancher documenté. ConvertOcrPdfAsync et ImageExtractTextAsync Attendez au moins DefaultOcrMaxWait, soit 10 minutes, alors laissez-les faire à leur rythme cancellationToken si l'appelant doit abandonner plus tôt.
Un 401 dans Pdf4meException.ResponseStatusCode. La clé est présente mais rejetée. Régénérez-la dans le PDF4me tableau de bord et vérifiez que la variable est visible par le processus. Sous Windows, set ne persiste pas d'une session à l'autre, veuillez donc utiliser setx et ouvrez un nouveau terminal.
ArgumentException avant que quoi que ce soit n'atteigne le réseau. Une vérification locale a échoué, généralement en raison d'un document vide, ce qui signifie que la lecture du fichier a renvoyé zéro octet. Vérifiez le chemin d'accès et assurez-vous que le fichier n'est pas verrouillé par un autre processus.
Vous avez indiqué un chemin de fichier et rien ne s'est passé avec ce fichier. Un argument de type chaîne de caractères est traité comme une référence blob ou un https URL, jamais un chemin local. Lisez le fichier et transmettez ses octets.
CreateThumbnailAsync introuvable. Les noms de méthodes de la version 1.x n'existent pas dans la version 2.0. Les miniatures sont désormais… CreateImagesAsync avec un ImageActionConsultez le tableau de migration.
Une erreur de compilation sur un type de modèle ou d'énumération. Les objets d'option et les modèles de résultats se trouvent dans Pdf4me.Client.Generated.Models, tandis que la plupart des énumérations qu'une action entreprend sont dans Pdf4me.ClientImportez les deux.
Questions fréquentes
Le kit de développement logiciel (SDK) PDF4me .NET est-il gratuit ?
Le Pdf4me.Client Le forfait est gratuit et MIT Ce logiciel est sous licence, son installation et sa redistribution sont donc gratuites. Ce paquet est un client pour le PDF4me API, qui est un service hébergé avec une formule gratuite et des abonnements payants, donc le traitement des documents consomme API Des crédits sont ajoutés à votre compte. Le code que vous utilisez est gratuit ; le traitement est facturé à la consommation.
Le client PDF4me .NET est-il open source ?
Oui. Le client est publié sous la licence MIT La licence et sa source se trouvent à l'adresse suivante : github.com/pdf4me/pdf4me-clientapi-dotnetUne mise en garde toutefois si vous envisagez de contribuer : src/Pdf4me.Client/Generated/ est produit par Kiota de la OpenAPI La description est entièrement remplacée à chaque régénération ; veuillez donc signaler tout problème dans cette arborescence plutôt que de la corriger. Le client et les fichiers de section associés sont écrits manuellement et constituent le lieu approprié pour une demande de fusion.
Quelles versions de .NET Pdf4me.Client prend-il en charge ?
Cibles de la version 2.0.0 .NET 8, .NET 9 et .NET 10, plus .NET Standard 2.0, ce qui signifie qu'il fonctionne également sur .NET Framework 4.6.2 et versions ultérieures. .NET Les frameworks 4.5.2 et 4.6.1 étaient pris en charge par la version 1.x et ne sont pas pris en charge par la version 2.0.
Comment convertir du HTML en PDF en C# ?
Appel ConvertHtmlToPdfAsync avec le HTML les octets du fichier, ou ConvertUrlToPdfAsync avec un URL chaîne de caractères, et écrivez la valeur renvoyée byte[] sur disque :
byte[] fromHtml = await client.ConvertHtmlToPdfAsync(File.ReadAllBytes("page.html"));
byte[] fromUrl = await client.ConvertUrlToPdfAsync("https://example.com");
File.WriteAllBytes("page.pdf", fromUrl);
Le rendu s'effectue côté serveur, il n'y a donc pas de moteur de navigateur à installer, à conteneuriser ou à corriger, ce qui représente le coût habituel de l'utilisation d'une bibliothèque locale.
Comment lire un fichier PDF en C# ?
Cela dépend de ce que l'on entend par « lire ». GetPdfMetadataAsync renvoie un DocMetadata avec le nombre de pages et PDF version. ExtractTextByExpressionAsync, GetTextByPositionAsync et GetTextAndCoordinatesAsync Extraire le texte, le dernier avec les positions. ExtractTableFromPdfAsync gère le contenu tabulaire, et ConvertOcrPdfAsync effectue un scan PDF consultables en premier. Ces actions renvoient des modèles typés plutôt qu'un byte[].
Est-il possible de créer un PDF en C# sans bibliothèque ?
Vous pouvez écrire le PDF La mise en forme manuelle du format d'octets est un exercice raisonnable pour une seule page de texte brut. Cependant, elle devient vite complexe, car les polices, les encodages, la compression et la table de correspondance doivent être corrects, et la tolérance aux erreurs varie selon les lecteurs. En pratique, le choix se résume à une bibliothèque de rendu locale à distribuer et à maintenir à jour, ou à une autre solution. API client comme celui-ci où le rendu s'effectue côté serveur. PDF La spécification est publiée sous la forme ISO 32000-2 si vous voulez vous rendre compte de son ampleur.