Remplacer du Texte dans un PDF via Python
Remplacer le texte dans toutes les pages d’un document PDF
Pour remplacer le texte dans toutes les pages d’un document PDF, vous devez d’abord utiliser TextFragmentAbsorber pour trouver la phrase particulière que vous souhaitez remplacer. Ensuite, vous devez parcourir tous les TextFragments pour remplacer le texte et modifier tous les autres attributs. Une fois cela fait, il vous suffit de sauvegarder le PDF de sortie en utilisant la méthode Save de l’objet Document. Le code suivant vous montre comment remplacer le texte dans toutes les pages d’un document PDF.
import aspose.pdf as ap
# Ouvrir le document
document = ap.Document(input_pdf)
# Créer un objet TextAbsorber pour trouver toutes les instances de la phrase de recherche
absorber = ap.text.TextFragmentAbsorber("format")
# Accepter l'absorbeur pour toutes les pages
document.pages.accept(absorber)
# Obtenir les fragments de texte extraits
collection = absorber.text_fragments
# Parcourir les fragments
for text_fragment in collection:
# Mettre à jour le texte et d'autres propriétés
text_fragment.text = "FORMAT"
text_fragment.text_state.font = ap.text.FontRepository.find_font("Verdana")
text_fragment.text_state.font_size = 22
text_fragment.text_state.foreground_color = ap.Color.blue
text_fragment.text_state.background_color = ap.Color.green
# Sauvegarder le document
document.save(output_pdf)
Remplacer le texte dans une région particulière de la page
Afin de remplacer le texte dans une région particulière de la page, nous devons d’abord instancier un objet TextFragmentAbsorber, spécifier la région de la page en utilisant la propriété TextSearchOptions.Rectangle, puis parcourir tous les TextFragments pour remplacer le texte. Une fois ces opérations terminées, il ne reste plus qu’à enregistrer le PDF de sortie en utilisant la méthode Save de l’objet Document. Le code suivant vous montre comment remplacer le texte dans toutes les pages d’un document PDF.
// charger le fichier PDF
Aspose.PDF.Document pdf = new Aspose.PDF.Document("c:/pdftest/programaticallyproducedpdf.pdf");
// instancier l'objet TextFragment Absorber
Aspose.PDF.Text.TextFragmentAbsorber TextFragmentAbsorberAddress = new Aspose.PDF.Text.TextFragmentAbsorber();
// rechercher du texte à l'intérieur des limites de la page
TextFragmentAbsorberAddress.TextSearchOptions.LimitToPageBounds = true;
// spécifier la région de la page pour les options de recherche de texte
TextFragmentAbsorberAddress.TextSearchOptions.Rectangle = new Aspose.PDF.Rectangle(100, 100, 200, 200);
// rechercher du texte à partir de la première page du fichier PDF
pdf.Pages[1].Accept(TextFragmentAbsorberAddress);
// parcourir chaque TextFragment
foreach( Aspose.PDF.Text.TextFragment tf in TextFragmentAbsorberAddress.TextFragments)
{
// mettre à jour le texte avec des caractères vides
tf.Text = "";
}
// enregistrer le fichier PDF mis à jour après le remplacement du texte
pdf.Save("c:/pdftest/TextUpdated.pdf");
Remplacer le texte basé sur une expression régulière
Si vous souhaitez remplacer certaines phrases basées sur une expression régulière, vous devez d’abord trouver toutes les phrases correspondant à cette expression régulière particulière en utilisant TextFragmentAbsorber. Vous devrez passer l’expression régulière en tant que paramètre au constructeur de TextFragmentAbsorber. Vous devez également créer un objet TextSearchOptions qui spécifie si l’expression régulière est utilisée ou non. Une fois que vous avez les phrases correspondantes dans TextFragments, vous devez parcourir chacune d’elles et mettre à jour si nécessaire. Enfin, vous devez enregistrer le PDF mis à jour en utilisant la méthode Save de l’objet Document. Le code suivant montre comment remplacer du texte basé sur une expression régulière.
// Pour des exemples complets et des fichiers de données, veuillez aller sur https://github.com/aspose-pdf/Aspose.PDF-for-.NET
// Le chemin vers le répertoire des documents.
string dataDir = RunExamples.GetDataDir_AsposePdf_Text();
// Ouvrir le document
Document pdfDocument = new Document(dataDir + "SearchRegularExpressionPage.pdf");
// Créer un objet TextAbsorber pour trouver toutes les phrases correspondant à l'expression régulière
TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber("\\d{4}-\\d{4}"); // Comme 1999-2000
// Définir l'option de recherche de texte pour spécifier l'utilisation de l'expression régulière
TextSearchOptions textSearchOptions = new TextSearchOptions(true);
textFragmentAbsorber.TextSearchOptions = textSearchOptions;
// Accepter l'absorbeur pour une seule page
pdfDocument.Pages[1].Accept(textFragmentAbsorber);
// Obtenir les fragments de texte extraits
TextFragmentCollection textFragmentCollection = textFragmentAbsorber.TextFragments;
// Parcourir les fragments
foreach (TextFragment textFragment in textFragmentCollection)
{
// Mettre à jour le texte et d'autres propriétés
textFragment.Text = "Nouvelle Phrase";
// Définir comme instance d'un objet.
textFragment.TextState.Font = FontRepository.FindFont("Verdana");
textFragment.TextState.FontSize = 22;
textFragment.TextState.ForegroundColor = Aspose.Pdf.Color.FromRgb(System.Drawing.Color.Blue);
textFragment.TextState.BackgroundColor = Aspose.Pdf.Color.FromRgb(System.Drawing.Color.Green);
}
dataDir = dataDir + "ReplaceTextonRegularExpression_out.pdf";
pdfDocument.Save(dataDir);
Remplacer les polices dans un fichier PDF existant
Aspose.PDF pour Python via .NET prend en charge la capacité de remplacer le texte dans un document PDF. Cependant, il arrive parfois que vous ayez besoin de remplacer uniquement la police utilisée dans le document PDF. Ainsi, au lieu de remplacer le texte, seule la police utilisée est remplacée. L’une des surcharges du constructeur TextFragmentAbsorber accepte un objet TextEditOptions comme argument, et nous pouvons utiliser la valeur RemoveUnusedFonts de l’énumération TextEditOptions.FontReplace pour répondre à nos besoins. Le code suivant montre comment remplacer la police dans un document PDF.
// Pour des exemples complets et des fichiers de données, veuillez visiter https://github.com/aspose-pdf/Aspose.PDF-for-.NET
// Le chemin vers le répertoire des documents.
string dataDir = RunExamples.GetDataDir_AsposePdf_Text();
// Charger le fichier PDF source
Document pdfDocument = new Document(dataDir + "ReplaceTextPage.pdf");
// Rechercher des fragments de texte et définir l'option d'édition pour supprimer les polices inutilisées
TextFragmentAbsorber absorber = new TextFragmentAbsorber(new TextEditOptions(TextEditOptions.FontReplace.RemoveUnusedFonts));
// Accepter l'absorbeur pour toutes les pages
pdfDocument.Pages.Accept(absorber);
// Parcourir tous les TextFragments
foreach (TextFragment textFragment in absorber.TextFragments)
{
// Si le nom de la police est ArialMT, remplacer le nom de la police par Arial
if (textFragment.TextState.Font.FontName == "Arial,Bold")
{
textFragment.TextState.Font = FontRepository.FindFont("Arial");
}
}
dataDir = dataDir + "ReplaceFonts_out.pdf";
// Enregistrer le document mis à jour
pdfDocument.Save(dataDir);
Le Remplacement de Texte devrait réorganiser automatiquement le Contenu des Pages
Aspose.PDF pour Python via .NET prend en charge la fonctionnalité de recherche et de remplacement de texte dans le fichier PDF. Cependant, récemment, certains clients ont rencontré des problèmes lors du remplacement de texte lorsque TextFragment particulier est remplacé par des contenus plus petits et que des espaces supplémentaires sont affichés dans le PDF résultant ou dans le cas où le TextFragment est remplacé par une chaîne plus longue, les mots chevauchent le contenu existant de la page. Ainsi, l’exigence était d’introduire un mécanisme selon lequel une fois que le texte à l’intérieur d’un document PDF est remplacé, le contenu devrait être réorganisé.
Afin de répondre aux scénarios mentionnés ci-dessus, Aspose.PDF pour Python via .NET a été amélioré afin que de tels problèmes n’apparaissent pas lors du remplacement de texte à l’intérieur d’un fichier PDF. Le code suivant montre comment remplacer du texte à l’intérieur d’un fichier PDF et le contenu de la page devrait être réorganisé automatiquement.
// Pour des exemples complets et des fichiers de données, veuillez consulter https://github.com/aspose-pdf/Aspose.PDF-for-.NET
// Le chemin vers le répertoire des documents.
string dataDir = RunExamples.GetDataDir_AsposePdf_Text();
// Charger le fichier PDF source
Document doc = new Document(dataDir + "ExtractTextPage.pdf");
// Créer un objet TextFragment Absorber avec une expression régulière
TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber("[TextFragmentAbsorber,companyname,Textbox,50]");
doc.Pages.Accept(textFragmentAbsorber);
// Remplacer chaque TextFragment
foreach (TextFragment textFragment in textFragmentAbsorber.TextFragments)
{
// Définir la police du fragment de texte à remplacer
textFragment.TextState.Font = FontRepository.FindFont("Arial");
// Définir la taille de la police
textFragment.TextState.FontSize = 12;
textFragment.TextState.ForegroundColor = Aspose.Pdf.Color.Navy;
// Remplacer le texte par une chaîne plus grande que l'espace réservé
textFragment.Text = "This is a Larger String for the Testing of this issue";
}
dataDir = dataDir + "RearrangeContentsUsingTextReplacement_out.pdf";
// Enregistrer le PDF résultant
doc.Save(dataDir);
Rendu des symboles remplaçables lors de la création de PDF
Les symboles remplaçables sont des symboles spéciaux dans une chaîne de texte qui peuvent être remplacés par le contenu correspondant au moment de l’exécution. Les symboles remplaçables actuellement pris en charge par le nouveau modèle d’objet document du namespace Aspose.PDF sont $P
, $p,
\n
, \r
. Les symboles $p
et $P
sont utilisés pour gérer la numérotation des pages au moment de l’exécution. $p
est remplacé par le numéro de la page où la classe Paragraph actuelle se trouve. $P
est remplacé par le nombre total de pages dans le document. Lors de l’ajout d’un TextFragment
à la collection de paragraphes des documents PDF, il ne prend pas en charge le retour à la ligne à l’intérieur du texte. Cependant, pour ajouter du texte avec un retour à la ligne, veuillez utiliser TextFragment
avec TextParagraph
:
- utilisez “\r\n” ou Environment.NewLine dans TextFragment au lieu d’un simple “\n” ;
- créez un objet TextParagraph. Il ajoutera du texte avec séparation de ligne ;
- ajoutez le TextFragment avec TextParagraph.AppendLine ;
- ajoutez le TextParagraph avec TextBuilder.AppendParagraph.
// Pour des exemples complets et des fichiers de données, veuillez consulter https://github.com/aspose-pdf/Aspose.PDF-for-.NET
// Le chemin vers le répertoire des documents.
string dataDir = RunExamples.GetDataDir_AsposePdf_Text();
Aspose.Pdf.Document pdfApplicationDoc = new Aspose.Pdf.Document();
Aspose.Pdf.Page applicationFirstPage = (Aspose.Pdf.Page)pdfApplicationDoc.Pages.Add();
// Initialiser un nouveau TextFragment avec du texte contenant les marqueurs de nouvelle ligne requis
Aspose.Pdf.Text.TextFragment textFragment = new Aspose.Pdf.Text.TextFragment("Nom du candidat : " + Environment.NewLine + " Joe Smoe");
// Définir les propriétés du fragment de texte si nécessaire
textFragment.TextState.FontSize = 12;
textFragment.TextState.Font = Aspose.Pdf.Text.FontRepository.FindFont("TimesNewRoman");
textFragment.TextState.BackgroundColor = Aspose.Pdf.Color.LightGray;
textFragment.TextState.ForegroundColor = Aspose.Pdf.Color.Red;
// Créer un objet TextParagraph
TextParagraph par = new TextParagraph();
// Ajouter un nouveau TextFragment au paragraphe
par.AppendLine(textFragment);
// Définir la position du paragraphe
par.Position = new Aspose.Pdf.Text.Position(100, 600);
// Créer un objet TextBuilder
TextBuilder textBuilder = new TextBuilder(applicationFirstPage);
// Ajouter le TextParagraph en utilisant TextBuilder
textBuilder.AppendParagraph(par);
dataDir = dataDir + "RenderingReplaceableSymbols_out.pdf";
pdfApplicationDoc.Save(dataDir);
Symboles remplaçables dans la zone d’en-tête/pied de page
Les symboles remplaçables peuvent également être placés à l’intérieur de la section En-tête/Pied de page du fichier PDF. Veuillez consulter l’extrait de code suivant pour plus de détails sur la façon d’ajouter un symbole remplaçable dans la section pied de page.
// Pour des exemples complets et des fichiers de données, veuillez aller à https://github.com/aspose-pdf/Aspose.PDF-for-.NET
// Le chemin vers le répertoire des documents.
string dataDir = RunExamples.GetDataDir_AsposePdf_Text();
Document doc = new Document();
Page page = doc.Pages.Add();
MarginInfo marginInfo = new MarginInfo();
marginInfo.Top = 90;
marginInfo.Bottom = 50;
marginInfo.Left = 50;
marginInfo.Right = 50;
// Assigner l'instance marginInfo à la propriété Margin de sec1.PageInfo
page.PageInfo.Margin = marginInfo;
HeaderFooter hfFirst = new HeaderFooter();
page.Header = hfFirst;
hfFirst.Margin.Left = 50;
hfFirst.Margin.Right = 50;
// Instancier un paragraphe de texte qui contiendra le contenu à afficher comme en-tête
TextFragment t1 = new TextFragment("titre du rapport");
t1.TextState.Font = FontRepository.FindFont("Arial");
t1.TextState.FontSize = 16;
t1.TextState.ForegroundColor = Aspose.Pdf.Color.Black;
t1.TextState.FontStyle = FontStyles.Bold;
t1.TextState.HorizontalAlignment = Aspose.Pdf.HorizontalAlignment.Center;
t1.TextState.LineSpacing = 5f;
hfFirst.Paragraphs.Add(t1);
TextFragment t2 = new TextFragment("Nom_du_Rapport");
t2.TextState.Font = FontRepository.FindFont("Arial");
t2.TextState.ForegroundColor = Aspose.Pdf.Color.Black;
t2.TextState.HorizontalAlignment = Aspose.Pdf.HorizontalAlignment.Center;
t2.TextState.LineSpacing = 5f;
t2.TextState.FontSize = 12;
hfFirst.Paragraphs.Add(t2);
// Créer un objet HeaderFooter pour la section
HeaderFooter hfFoot = new HeaderFooter();
// Définir l'objet HeaderFooter pour les pieds de page impairs et pairs
page.Footer = hfFoot;
hfFoot.Margin.Left = 50;
hfFoot.Margin.Right = 50;
// Ajouter un paragraphe de texte contenant le numéro de page actuel sur le nombre total de pages
TextFragment t3 = new TextFragment("Généré à la date de test");
TextFragment t4 = new TextFragment("nom du rapport ");
TextFragment t5 = new TextFragment("Page $p de $P");
// Instancier un objet table
Table tab2 = new Table();
// Ajouter la table dans la collection de paragraphes de la section souhaitée
hfFoot.Paragraphs.Add(tab2);
// Définir les largeurs des colonnes de la table
tab2.ColumnWidths = "165 172 165";
// Créer des lignes dans la table puis des cellules dans les lignes
Row row3 = tab2.Rows.Add();
row3.Cells.Add();
row3.Cells.Add();
row3.Cells.Add();
// Définir l'alignement vertical du texte comme centré
row3.Cells[0].Alignment = Aspose.Pdf.HorizontalAlignment.Left;
row3.Cells[1].Alignment = Aspose.Pdf.HorizontalAlignment.Center;
row3.Cells[2].Alignment = Aspose.Pdf.HorizontalAlignment.Right;
row3.Cells[0].Paragraphs.Add(t3);
row3.Cells[1].Paragraphs.Add(t4);
row3.Cells[2].Paragraphs.Add(t5);
// Sec1.Paragraphs.Add(New Text("Aspose.Total pour Java est une compilation de chaque composant Java proposé par Aspose. Il est compilé sur un#$NL" + "basis quotidien pour s'assurer qu'il contient les versions les plus récentes de chacun de nos composants Java. #$NL " + "En utilisant Aspose.Total pour Java, les développeurs peuvent créer une large gamme d'applications. #$NL #$NL #$NP" + "Aspose.Total pour Java est une compilation de chaque composant Java proposé par Aspose. Il est compilé sur un#$NL" + "basis quotidien pour s'assurer qu'il contient les versions les plus récentes de chacun de nos composants Java. #$NL " + "En utilisant Aspose.Total pour Java, les développeurs peuvent créer une large gamme d'applications. #$NL #$NL #$NP" + "Aspose.Total pour Java est une compilation de chaque composant Java proposé par Aspose. Il est compilé sur un#$NL" + "basis quotidien pour s'assurer qu'il contient les versions les plus récentes de chacun de nos composants Java. #$NL " + "En utilisant Aspose.Total pour Java, les développeurs peuvent créer une large gamme d'applications. #$NL #$NL"))
Table table = new Table();
table.ColumnWidths = "33% 33% 34%";
table.DefaultCellPadding = new MarginInfo();
table.DefaultCellPadding.Top = 10;
table.DefaultCellPadding.Bottom = 10;
// Ajouter la table dans la collection de paragraphes de la section souhaitée
page.Paragraphs.Add(table);
// Définir la bordure de cellule par défaut à l'aide de l'objet BorderInfo
table.DefaultCellBorder = new BorderInfo(BorderSide.All, 0.1f);
// Définir la bordure de la table à l'aide d'un autre objet BorderInfo personnalisé
table.Border = new BorderInfo(BorderSide.All, 1f);
table.RepeatingRowsCount = 1;
// Créer des lignes dans la table puis des cellules dans les lignes
Row row1 = table.Rows.Add();
row1.Cells.Add("col1");
row1.Cells.Add("col2");
row1.Cells.Add("col3");
const string CRLF = "\r\n";
for (int i = 0; i <= 10; i++)
{
Row row = table.Rows.Add();
row.IsRowBroken = true;
for (int c = 0; c <= 2; c++)
{
Cell c1;
if (c == 2)
c1 = row.Cells.Add("Aspose.Total pour Java est une compilation de chaque composant Java proposé par Aspose. Il est compilé sur un" + CRLF + "basis quotidien pour s'assurer qu'il contient les versions les plus récentes de chacun de nos composants Java. " + CRLF + "basis quotidien pour s'assurer qu'il contient les versions les plus récentes de chacun de nos composants Java. " + CRLF + "En utilisant Aspose.Total pour Java, les développeurs peuvent créer une large gamme d'applications.");
else
c1 = row.Cells.Add("item1" + c);
c1.Margin = new MarginInfo();
c1.Margin.Left = 30;
c1.Margin.Top = 10;
c1.Margin.Bottom = 10;
}
}
dataDir = dataDir + "ReplaceableSymbolsInHeaderFooter_out.pdf";
doc.Save(dataDir);
Supprimer les polices inutilisées d’un fichier PDF
Aspose.PDF pour Python via .NET prend en charge la fonctionnalité d’incorporer des polices lors de la création d’un document PDF, ainsi que la capacité d’incorporer des polices dans des fichiers PDF existants. À partir d’Aspose.PDF pour Python via .NET 7.3.0, il vous permet également de supprimer les polices en double ou inutilisées des documents PDF.
Pour remplacer les polices, utilisez l’approche suivante :
- Appelez la classe TextFragmentAbsorber.
- Appelez le paramètre TextEditOptions.FontReplace.RemoveUnusedFonts de la classe TextFragmentAbsorber. (Cela supprime les polices qui sont devenues inutilisées lors du remplacement de la police).
- Définissez la police individuellement pour chaque fragment de texte.
Le code suivant remplace la police pour tous les fragments de texte de toutes les pages du document et supprime les polices inutilisées.
// Pour des exemples complets et des fichiers de données, veuillez consulter https://github.com/aspose-pdf/Aspose.PDF-for-.NET
// Le chemin vers le répertoire des documents.
string dataDir = RunExamples.GetDataDir_AsposePdf_Text();
// Charger le fichier PDF source
Document doc = new Document(dataDir + "ReplaceTextPage.pdf");
TextFragmentAbsorber absorber = new TextFragmentAbsorber(new TextEditOptions(TextEditOptions.FontReplace.RemoveUnusedFonts));
doc.Pages.Accept(absorber);
// Itérer à travers tous les TextFragments
foreach (TextFragment textFragment in absorber.TextFragments)
{
textFragment.TextState.Font = FontRepository.FindFont("Arial, Bold");
}
dataDir = dataDir + "RemoveUnusedFonts_out.pdf";
// Sauvegarder le document mis à jour
doc.Save(dataDir);
Supprimer Tout le Texte d’un Document PDF
Supprimer Tout le Texte en Utilisant des Opérateurs
Dans certaines opérations sur le texte, vous devez supprimer tout le texte d’un document PDF et pour cela, vous devez généralement définir le texte trouvé comme une chaîne de caractères vide. Le point est que changer le texte pour une multitude de fragments de texte entraîne un certain nombre de vérifications et d’opérations d’ajustement de position du texte. Ils sont essentiels dans les scénarios d’édition de texte. La difficulté est que vous ne pouvez pas déterminer combien de fragments de texte seront supprimés dans le scénario où ils sont traités dans une boucle.
Par conséquent, nous recommandons d’utiliser une autre approche pour le scénario de suppression de tout le texte des pages PDF. Veuillez considérer l’extrait de code suivant qui fonctionne très rapidement.
// Pour des exemples complets et des fichiers de données, veuillez consulter https://github.com/aspose-pdf/Aspose.PDF-for-.NET
// Le chemin vers le répertoire des documents.
string dataDir = RunExamples.GetDataDir_AsposePdf_Text();
// Ouvrir le document
Document pdfDocument = new Document(dataDir + "RemoveAllText.pdf");
// Boucle à travers toutes les pages du document PDF
for (int i = 1; i <= pdfDocument.Pages.Count; i++)
{
Page page = pdfDocument.Pages[i];
OperatorSelector operatorSelector = new OperatorSelector(new Aspose.Pdf.Operators.TextShowOperator());
// Sélectionner tout le texte sur la page
page.Contents.Accept(operatorSelector);
// Supprimer tout le texte
page.Contents.Delete(operatorSelector.Selected);
}
// Enregistrer le document
pdfDocument.Save(dataDir + "RemoveAllText_out.pdf", Aspose.Pdf.SaveFormat.Pdf);
{ “@context”: “http://schema.org”, “@type”: “SoftwareApplication”, “name”: “Aspose.PDF pour Python via .NET Library”, “image”: “https://www.aspose.cloud/templates/aspose/img/products/pdf/aspose_pdf-for-python-net.svg", “url”: “https://www.aspose.com/", “publisher”: { “@type”: “Organization”, “name”: “Aspose.PDF”, “url”: “https://products.aspose.com/pdf", “logo”: “https://www.aspose.cloud/templates/aspose/img/products/pdf/aspose_pdf-for-python-net.svg", “alternateName”: “Aspose”, “sameAs”: [ “https://facebook.com/aspose.pdf/”, “https://twitter.com/asposepdf”, “https://www.youtube.com/channel/UCmV9sEg_QWYPi6BJJs7ELOg/featured”, “https://www.linkedin.com/company/aspose”, “https://stackoverflow.com/questions/tagged/aspose”, “https://aspose.quora.com/”, “https://aspose.github.io/” ], “contactPoint”: [ { “@type”: “ContactPoint”, “telephone”: “+1 903 306 1676”, “contactType”: “ventes”, “areaServed”: “US”, “availableLanguage”: “en” }, { “@type”: “ContactPoint”, “telephone”: “+44 141 628 8900”, “contactType”: “ventes”, “areaServed”: “GB”, “availableLanguage”: “en” }, { “@type”: “ContactPoint”, “telephone”: “+61 2 8006 6987”, “contactType”: “ventes”, “areaServed”: “AU”, “availableLanguage”: “en” } ] }, “offers”: { “@type”: “Offer”, “price”: “1199”, “priceCurrency”: “USD” }, “applicationCategory”: “Bibliothèque de manipulation PDF pour Python”, “downloadUrl”: “https://www.nuget.org/packages/Aspose.PDF/", “operatingSystem”: “Windows, MacOS, Linux”, “screenshot”: “https://docs.aspose.com/pdf/python-net/create-pdf-document/screenshot.png", “softwareVersion”: “2024.1”, “aggregateRating”: { “@type”: “AggregateRating”, “ratingValue”: “5”, “ratingCount”: “16” } }