Remplacer le texte dans un PDF en utilisant C++
Parfois, une tâche apparaît pour corriger ou remplacer du texte dans un document PDF. Essayer de le faire manuellement sera une tâche ardue, donc voici la solution à ce problème.
Honnêtement, éditer un fichier PDF n’est pas une tâche facile. Ainsi, une situation où vous devez trouver et remplacer un mot par un autre tout en éditant un fichier PDF sera très difficile car cela vous prendra beaucoup de temps. De plus, vous pouvez rencontrer de nombreux problèmes avec votre sortie, tels que le formatage ou des polices cassées. Si vous souhaitez facilement trouver et remplacer du texte dans des fichiers PDF, nous vous recommandons d’utiliser le logiciel Aspose.Pdf car il fera le travail en quelques minutes.
Dans cet article, nous vous montrerons comment trouver et remplacer avec succès du texte dans vos fichiers PDF en utilisant Aspose.PDF pour C++.
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. Après cela, vous devez parcourir tous les TextFragments pour remplacer le texte et modifier d’autres attributs. Une fois cela fait, vous n’avez besoin que d’enregistrer le PDF de sortie en utilisant la méthode Save de l’objet Document. Le code ci-dessous vous montre comment remplacer le texte dans toutes les pages d’un document PDF.
using namespace System;
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Text;
void ReplaceTextOnAllPages() {
String _dataDir("C:\\Samples\\");
auto document = MakeObject<Document>(_dataDir + u"sample.pdf");
// Créer un objet TextAbsorber pour trouver toutes les instances de la phrase de recherche entrée
auto textFragmentAbsorber = MakeObject<TextFragmentAbsorber>("Web");
// Accepter l'absorbeur pour la première page du document
document->get_Pages()->Accept(textFragmentAbsorber);
// Obtenir les fragments de texte extraits dans la collection
auto textFragmentCollection = textFragmentAbsorber->get_TextFragments();
// Boucle à travers les fragments
for (auto textFragment : textFragmentCollection) {
// Mettre à jour le texte et d'autres propriétés
textFragment->set_Text(u"World Wide Web");
textFragment->get_TextState()->set_Font(FontRepository::FindFont(u"Verdana"));
textFragment->get_TextState()->set_FontSize(12);
textFragment->get_TextState()->set_ForegroundColor(Color::get_Blue());
textFragment->get_TextState()->set_BackgroundColor(Color::get_Gray());
}
// Enregistrer le fichier PDF mis à jour
document->Save(_dataDir + u"Updated_Text.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, nous avons seulement besoin d’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.
void ReplaceTextInParticularRegion() {
String _dataDir("C:\\Samples\\");
// charger le fichier PDF
auto document = MakeObject<Document>(_dataDir + u"sample.pdf");
// instancier l'objet TextFragment Absorber
auto textFragmentAbsorber = MakeObject<TextFragmentAbsorber>("PDF");
// rechercher du texte dans les limites de la page
textFragmentAbsorber->get_TextSearchOptions()->set_LimitToPageBounds(true);
// spécifier la région de la page pour les options de recherche de texte
textFragmentAbsorber->get_TextSearchOptions()->set_Rectangle(new Rectangle(100, 700, 400, 770));
// rechercher du texte à partir de la première page du fichier PDF
document->get_Pages()->idx_get(1)->Accept(textFragmentAbsorber);
// parcourir chaque TextFragment
for (auto tf : textFragmentAbsorber->get_TextFragments()) {
// remplacer le texte par "---"
tf->set_Text(u"---");
}
// Enregistrer le fichier PDF mis à jour
document->Save(_dataDir + u"Updated_Text.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 les parcourir et les mettre à jour selon les besoins. Enfin, vous devez enregistrer le PDF mis à jour en utilisant la méthode Save de l’objet Document. Le fragment de code suivant vous montre comment remplacer le texte basé sur une expression régulière.
void ReplaceTextWithRegularExpression() {
String _dataDir("C:\\Samples\\");
// load PDF file
auto document = MakeObject<Document>(_dataDir + u"Sample.pdf");
// Create TextAbsorber object to find all instances of the input search phrase
auto textFragmentAbsorber = MakeObject<TextFragmentAbsorber>("\\d{4}-\\d{4}");
// like 1999-2000
// Set text search option to specify regular expression usage
auto textSearchOptions = new TextSearchOptions(true);
textFragmentAbsorber->set_TextSearchOptions(textSearchOptions);
// Accept the absorber for first page of document
document->get_Pages()->Accept(textFragmentAbsorber);
// Get the extracted text fragments into collection
auto textFragmentCollection = textFragmentAbsorber->get_TextFragments();
// Loop through the fragments
for (auto textFragment : textFragmentCollection) {
// Update text and other properties
textFragment->set_Text(u"ABCD-EFGH");
textFragment->get_TextState()->set_Font(FontRepository::FindFont(u"Verdana"));
textFragment->get_TextState()->set_FontSize(12);
textFragment->get_TextState()->set_ForegroundColor(Color::get_Blue());
textFragment->get_TextState()->set_BackgroundColor(Color::get_Gray());
}
// Save the updated PDF file
document->Save(_dataDir + u"Updated_Text.pdf");
}
Remplacer les polices dans un fichier PDF existant
Aspose.PDF pour C++ prend en charge la capacité de remplacer le texte dans un document PDF. Cependant, parfois, vous avez besoin de ne remplacer que la police utilisée dans le document PDF. 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. L’extrait de code suivant montre comment remplacer la police à l’intérieur du document PDF.
void ReplaceFonts() {
String _dataDir("C:\\Samples\\");
// Instancier l'objet Document
auto document = MakeObject<Document>(_dataDir + u"sample.pdf");
// Rechercher les fragments de texte et définir l'option d'édition pour supprimer les polices inutilisées
auto textFragmentAbsorber = MakeObject<TextFragmentAbsorber>(
MakeObject<TextEditOptions>(TextEditOptions::FontReplace::RemoveUnusedFonts));
// Accepter l'absorbeur pour toutes les pages du document
document->get_Pages()->Accept(textFragmentAbsorber);
// parcourir tous les TextFragments
auto textFragmentCollection = textFragmentAbsorber->get_TextFragments();
for (auto textFragment : textFragmentCollection) {
String fontName = textFragment->get_TextState()->get_Font()->get_FontName();
// si le nom de la police est ArialMT, remplacer le nom de la police par Arial
if (fontName.Equals(u"ArialMT")) {
textFragment->get_TextState()->set_Font(FontRepository::FindFont(u"Arial"));
}
}
// Enregistrer le fichier PDF mis à jour
document->Save(_dataDir + u"Updated_Text.pdf");
}
Dans le prochain extrait de code, vous verrez comment utiliser une police non anglaise lors du remplacement de texte :
void UseNonEnglishFontWhenReplacingText() {
String _dataDir("C:\\Samples\\");
// Instancier un objet Document
auto document = MakeObject<Document>(_dataDir + u"sample.pdf");
// Changeons chaque mot "PDF" en un texte japonais avec une police spécifique
// MSGothic qui pourrait être installée dans le système d'exploitation
// De plus, cela peut être une autre police qui supporte les hiéroglyphes
auto textFragmentAbsorber = MakeObject<TextFragmentAbsorber>("PDF");
// Créer une instance des options de recherche de texte
auto searchOptions = MakeObject<TextSearchOptions>(true);
textFragmentAbsorber->set_TextSearchOptions(searchOptions);
// Accepter l'absorbeur pour toutes les pages du document
document->get_Pages()->Accept(textFragmentAbsorber);
// Obtenir les fragments de texte extraits dans la collection
auto textFragmentCollection = textFragmentAbsorber->get_TextFragments();
// Boucle à travers les fragments
for (auto textFragment : textFragmentCollection) {
// Mettre à jour le texte et d'autres propriétés
textFragment->set_Text(u"ファイル");
textFragment->get_TextState()->set_Font(FontRepository::FindFont(u"TakaoMincho"));
textFragment->get_TextState()->set_FontSize(12);
textFragment->get_TextState()->set_ForegroundColor(Color::get_Blue());
textFragment->get_TextState()->set_BackgroundColor(Color::get_Gray());
}
// Enregistrer le document mis à jour
document->Save(_dataDir + u"Japanese_Text.pdf");
}
Le remplacement de texte devrait réorganiser automatiquement le contenu de la page
Aspose.PDF pour C++ prend en charge la recherche et le remplacement de texte dans un fichier PDF. Récemment, cependant, certains clients ont rencontré des problèmes lors du remplacement de texte, où un TextFragment particulier est remplacé par un contenu plus petit et un espace blanc supplémentaire est affiché dans le PDF résultant, ou si le TextFragment est remplacé par une chaîne plus longue, alors les mots se chevauchent avec le contenu de la page existante. Ainsi, il a été nécessaire d’introduire un mécanisme qui, après avoir remplacé le texte dans le document PDF, réorganise son contenu.
Pour répondre aux scénarios susmentionnés, Aspose.PDF pour C++ a été amélioré afin que de tels problèmes ne se produisent pas lors du remplacement de texte dans un fichier PDF. Le fragment de code suivant démontre comment remplacer le texte dans un fichier PDF et le contenu de la page doit être réorganisé automatiquement.
void RearrangeContent() {
String _dataDir("C:\\Samples\\");
// Instantiate Document object
auto document = MakeObject<Document>(_dataDir + u"sample.pdf");
// Create TextFragment Absorber object with regular expression
auto textFragmentAbsorber = MakeObject<TextFragmentAbsorber>("[PDF,Web]");
auto textSearchOptions = MakeObject<TextSearchOptions>(true);
textFragmentAbsorber->set_TextSearchOptions(textSearchOptions);
// You also can specify the ReplaceAdjustment.WholeWordsHyphenation option to
// wrap text on the next or current line if the current line becomes too long or
// short after replacement:
//textFragmentAbsorber->get_TextReplaceOptions()->set_ReplaceAdjustmentAction(TextReplaceOptions::ReplaceAdjustment::WholeWordsHyphenation);
// Accept the absorber for all pages of document
document->get_Pages()->Accept(textFragmentAbsorber);
// Get the extracted text fragments into collection
auto textFragmentCollection = textFragmentAbsorber->get_TextFragments();
// Replace each TextFragment
for (auto textFragment : textFragmentCollection) {
// Set font of text fragment being replaced
textFragment->get_TextState()->set_Font(FontRepository::FindFont(u"Arial"));
// Set font size
textFragment->get_TextState()->set_FontSize(10);
textFragment->get_TextState()->set_ForegroundColor(Color::get_Blue());
textFragment->get_TextState()->set_BackgroundColor(Color::get_Gray());
// Replace the text with larger string than placeholder
textFragment->set_Text(u"This is a larger string for the testing of this feature");
}
// Save resultant PDF
document->Save(_dataDir + u"RearrangeContentsUsingTextReplacement_out.pdf");
}
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 de 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ù se trouve la classe Paragraph actuelle. $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 saut de ligne à l’intérieur du texte. Cependant, afin d’ajouter du texte avec un saut de ligne, veuillez utiliser TextFragment
avec TextParagraph
:
- utilisez “\r\n” ou Environment.NewLine dans TextFragment au lieu d’un seul “\n” ;
- créez un objet TextParagraph. Il ajoutera du texte avec une séparation de ligne ;
- ajoutez le TextFragment avec TextParagraph.AppendLine ;
- ajoutez le TextParagraph avec TextBuilder.AppendParagraph.
void RenderingReplaceableSymbols() {
String _dataDir("C:\\Samples\\");
// chargez le fichier PDF
auto document = MakeObject<Document>(_dataDir + u"sample.pdf");
auto page = document->get_Pages()->Add();
// Initialiser un nouveau TextFragment avec du texte contenant les marqueurs de nouvelle ligne requis
auto textFragment = MakeObject<TextFragment>("Nom du demandeur : \r\n Joe Smoe");
// Définir les propriétés du fragment de texte si nécessaire
textFragment->get_TextState()->set_FontSize(12);
textFragment->get_TextState()->set_Font(FontRepository::FindFont(u"TimesNewRoman"));
textFragment->get_TextState()->set_BackgroundColor(Color::get_LightGray());
textFragment->get_TextState()->set_ForegroundColor(Color::get_Red());
// Créer un objet TextParagraph
auto par = MakeObject<TextParagraph>();
// Ajouter un nouveau TextFragment au paragraphe
par->AppendLine(textFragment);
// Définir la position du paragraphe
par->set_Position(MakeObject<Position>(100, 600));
// Créer un objet TextBuilder
auto textBuilder = MakeObject<TextBuilder>(page);
// Ajouter le TextParagraph en utilisant TextBuilder
textBuilder->AppendParagraph(par);
document->Save(_dataDir + u"RenderingReplaceableSymbols_out.pdf");
}
Symboles remplaçables dans la zone En-tête/Pied de page
Le symbole remplaçable peut également être placé à l’intérieur de la section en-tête/pied de page du fichier PDF. Consultez l’extrait de code suivant pour voir comment ajouter un symbole remplaçable à une section de pied de page.
void ReplaceableSymbolsInHeaderFooterArea() {
auto document = MakeObject<Document>();
auto page = doc.getPages().add();
auto marginInfo = MakeObject<MarginInfo>();
marginInfo->set_Top(90);
marginInfo->set_Bottom(50);
marginInfo->set_Left(50);
marginInfo->set_Right(50);
// Assigner l'instance marginInfo à la propriété Margin de PageInfo
page.getPageInfo()->set_Margin(marginInfo);
auto hfFirst = MakeObject<HeaderFooter>();
page->set_Header(hfFirst);
hfFirst->get_Margin()->set_Left(50);
hfFirst->get_Margin()->set_Right(50);
// Instancier un paragraphe de texte qui stockera le contenu à afficher comme en-tête
auto t1 = MakeObject<TextFragment>("titre du rapport");
t1->get_TextState()->set_Font(FontRepository::FindFont(u"Arial"));
t1->get_TextState()->set_FontSize(16);
t1->get_TextState()->set_ForegroundColor(Color::get_Black());
t1->get_TextState()->set_FontStyle(FontStyles::Bold);
t1->get_TextState()->set_HorizontalAlignment(HorizontalAlignment::Center);
t1->get_TextState()->set_LineSpacing(5.0f);
hfFirst->get_Paragraphs()->Add(t1);
auto t2 = MakeObject<TextFragment>("Nom_Rapport");
t2->get_TextState()->set_Font(FontRepository::FindFont(u"Arial"));
t2->get_TextState()->set_ForegroundColor(Color::get_Black());
t2->get_TextState()->set_HorizontalAlignment(HorizontalAlignment::Center);
t2->get_TextState()->set_LineSpacing(5.0f);
t2->get_TextState()->set_FontSize(12);
hfFirst->get_Paragraphs()->Add(t2);
// Créer un objet HeaderFooter pour la section
auto hfFoot = MakeObject<HeaderFooter>();
// Définir l'objet HeaderFooter pour le pied de page impair et pair
page->set_Footer(hfFoot);
hfFoot->get_Margin()->set_Left(50);
hfFoot->get_Margin()->set_Right(50);
// Ajouter un paragraphe de texte contenant le numéro de page actuel sur le nombre total de pages
auto t3 = MakeObject<TextFragment>("Généré à la date de test");
auto t4 = MakeObject<TextFragment>("nom du rapport ");
auto t5 = MakeObject<TextFragment>("Page $p de $P");
// Instancier un objet table
auto tab2 = MakeObject<Table>();
// Ajouter le tableau dans la collection de paragraphes de la section souhaitée
hfFoot->get_Paragraphs()->Add(tab2);
// Définir les largeurs des colonnes du tableau
tab2->set_ColumnWidths(u"165 172 165");
// Créer des lignes dans le tableau puis des cellules dans les lignes
auto row3 = tab2->get_Rows()->Add();
row3->get_Cells()->Add();
row3->get_Cells()->Add();
row3->get_Cells()->Add();
// Définir l'alignement vertical du texte comme centré
row3->get_Cells()->idx_get(0)->set_Alignment(HorizontalAlignment::Left);
row3->get_Cells()->idx_get(1)->set_Alignment(HorizontalAlignment::Center);
row3->get_Cells()->idx_get(2)->set_Alignment(HorizontalAlignment::Right);
row3->get_Cells()->idx_get(0)->get_Paragraphs()->Add(t3);
row3->get_Cells()->idx_get(1)->get_Paragraphs()->Add(t4);
row3->get_Cells()->idx_get(2)->get_Paragraphs()->Add(t5);
auto table = MakeObject<Table>();
table->set_ColumnWidths(u"33% 33% 34%");
table->set_DefaultCellPadding(new MarginInfo());
table->get_DefaultCellPadding()->set_Top(10);
table->get_DefaultCellPadding()->set_Bottom(10);
// Ajouter le tableau dans la collection de paragraphes de la section souhaitée
page.getParagraphs().add(table);
// Définir la bordure de cellule par défaut à l'aide de l'objet BorderInfo
table->set_DefaultCellBorder(MakeObject<BorderInfo>(BorderSide::All, 0.1f));
// Définir la bordure du tableau à l'aide d'un autre objet BorderInfo personnalisé
table->set_Border(MakeObject<BorderInfo>(BorderSide::All, 1.0f));
table->set_RepeatingRowsCount(1);
// Créer des lignes dans le tableau puis des cellules dans les lignes
auto row1 = table->get_Rows()->Add();
row1->get_Cells()->Add(u"col1");
row1->get_Cells()->Add(u"col2");
row1->get_Cells()->Add(u"col3");
String CRLF ("\r\n");
for (int i = 0; i <= 10; i++) {
auto row = table->get_Rows()->Add();
row->set_IsRowBroken(true);
for (int c = 0; c <= 2; c++) {
SharedPtr<Cell> c1;
if (c == 2)
c1 = row->get_Cells()->Add(
u"Aspose.Total pour C++ est une compilation de chaque composant Java proposé par Aspose. Il est compilé sur une"
+ CRLF
+ u"base quotidienne pour s'assurer qu'il contient les versions les plus récentes de chacun de nos composants Java. "
+ CRLF
+ u"base quotidienne pour s'assurer qu'il contient les versions les plus récentes de chacun de nos composants Java. "
+ CRLF
+ u"En utilisant Aspose.Total pour C++, les développeurs peuvent créer une large gamme d'applications.");
else
c1 = row->get_Cells()->Add(u"item1" + c);
c1->set_Margin(new MarginInfo());
c1->get_Margin()->set_Left(30);
c1->get_Margin()->set_Top(10);
c1->get_Margin()->set_Bottom(10);
}
}
_dataDir = _dataDir + "ReplaceableSymbolsInHeaderFooter_out.pdf";
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 du document PDF, et pour cela, vous devez généralement définir le texte trouvé comme une valeur de chaîne vide. Le fait est que changer le texte pour un ensemble de fragments de texte entraîne un certain nombre d’opérations pour vérifier et ajuster la position du texte. Elles sont nécessaires dans les scripts d’édition de texte. La difficulté réside dans le fait que vous ne pouvez pas déterminer combien de morceaux de texte seront supprimés dans le script où ils sont traités dans la boucle.
Par conséquent, nous recommandons d’utiliser une approche différente pour le scénario de suppression de tout le texte des pages PDF.
Le code suivant montre comment résoudre cette tâche rapidement.
void RemoveAllTextUsingOperators() {
String _dataDir("C:\\Samples\\");
// Open document
auto document = MakeObject<Document>(_dataDir + u"sample.pdf");
// Loop through all pages of PDF Document
for (int i = 1; i <= document->get_Pages()->get_Count(); i++) {
auto page = document->get_Pages()->idx_get(i);
auto operatorSelector = MakeObject<OperatorSelector>(MakeObject<Aspose::Pdf::Operators::TextShowOperator>());
// Select all text on the page
page->get_Contents()->Accept(operatorSelector);
// Delete all text
page->get_Contents()->Delete(operatorSelector->get_Selected());
}
// Save the document
document->Save(_dataDir + u"RemoveAllText_out.pdf");
}