Je cherche Internet depuis 2 semaines et j'ai trouvé des solutions intéressantes à mon problème, mais rien ne semble me donner la réponse.
Mon but est de faire ce qui suit:
Je veux trouver un texte dans un fichier PDF statique et remplacer ce texte par un autre texte. J'aimerais conserver la conception du contenu. Est-ce vraiment si difficile?
J'ai trouvé un moyen mais j'ai perdu toute l'information:
using (PdfReader reader = new PdfReader(path))
{
StringBuilder text = new StringBuilder();
for (int i = 1; i <= reader.NumberOfPages; i++)
{
text.Append(PdfTextExtractor.GetTextFromPage(reader, i));
text.Replace(txt_SuchenNach.Text, txt_ErsetzenMit.Text);
}
return text.ToString();
}
Le deuxième essai que j’avais était bien meilleur, mais il me fallait des champs dans lesquels je peux changer le texte:
string fileNameExisting =path;
string fileNameNew = @"C:\TEST.pdf";
using (FileStream existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (FileStream newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
// PDF öffnen
PdfReader pdfReader = new PdfReader(existingFileStream);
PdfStamper stamper = new PdfStamper(pdfReader, newFileStream);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (string fieldKey in fieldKeys)
{
var value = pdfReader.AcroFields.GetField(fieldKey);
form.SetField(fieldKey, value.Replace(txt_SuchenNach.Text, txt_ErsetzenMit.Text));
}
// Textfeld unbearbeitbar machen (sieht aus wie normaler text)
stamper.FormFlattening = true;
stamper.Close();
pdfReader.Close();
}
Cela conserve la mise en forme du reste du texte et ne modifie que le texte recherché. J'ai besoin d'une solution pour le texte qui n'est pas dans un champ de texte.
merci pour toutes vos réponses et votre aide.
Le problème général est que les objets texte peuvent utiliser des polices incorporées avec des glyphes spécifiques affectés à des lettres spécifiques. C'est à dire. Si vous avez un objet texte avec du texte tel que "abcdef", la police incorporée peut contenir des glyphes uniquement pour ces lettres ("abcdef"), mais pas pour d'autres lettres. Donc, si vous remplacez "abcdef" par "xyz", le PDF n'affichera pas ces "xyz", car aucun glyphe n'est disponible pour l'affichage de ces lettres.
Je considérerais donc le flux de travail suivant:
J'ai travaillé sur la même exigence et je peux y parvenir en suivant les étapes suivantes.
Étape 1: Localisation du fichier PDF source et du chemin du fichier de destination
Étape 2: Lire le fichier PDF source et rechercher l’emplacement de la chaîne à remplacer
Étape 3: Remplacement de la chaîne par une nouvelle.
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using PDFExtraction;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace PDFReplaceTextUsingItextSharp
{
public partial class ExtractPdf : System.Web.UI.Page
{
static iTextSharp.text.pdf.PdfStamper stamper = null;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Replace_Click(object sender, EventArgs e)
{
string ReplacingVariable = txtReplace.Text;
string sourceFile = "Source File Path";
string descFile = "Destination File Path";
PdfReader pReader = new PdfReader(sourceFile);
stamper = new iTextSharp.text.pdf.PdfStamper(pReader, new System.IO.FileStream(descFile, System.IO.FileMode.Create));
PDFTextGetter("ExistingVariableinPDF", ReplacingVariable , StringComparison.CurrentCultureIgnoreCase, sourceFile, descFile);
stamper.Close();
pReader.Close();
}
/// <summary>
/// This method is used to search for the location words in pdf and update it with the words given from replacingText variable
/// </summary>
/// <param name="pSearch">Searchable String</param>
/// <param name="replacingText">Replacing String</param>
/// <param name="SC">Case Ignorance</param>
/// <param name="SourceFile">Path of the source file</param>
/// <param name="DestinationFile">Path of the destination file</param>
public static void PDFTextGetter(string pSearch, string replacingText, StringComparison SC, string SourceFile, string DestinationFile)
{
try
{
iTextSharp.text.pdf.PdfContentByte cb = null;
iTextSharp.text.pdf.PdfContentByte cb2 = null;
iTextSharp.text.pdf.PdfWriter writer = null;
iTextSharp.text.pdf.BaseFont bf = null;
if (System.IO.File.Exists(SourceFile))
{
PdfReader pReader = new PdfReader(SourceFile);
for (int page = 1; page <= pReader.NumberOfPages; page++)
{
myLocationTextExtractionStrategy strategy = new myLocationTextExtractionStrategy();
cb = stamper.GetOverContent(page);
cb2 = stamper.GetOverContent(page);
//Send some data contained in PdfContentByte, looks like the first is always cero for me and the second 100,
//but i'm not sure if this could change in some cases
strategy.UndercontentCharacterSpacing = (int)cb.CharacterSpacing;
strategy.UndercontentHorizontalScaling = (int)cb.HorizontalScaling;
//It's not really needed to get the text back, but we have to call this line ALWAYS,
//because it triggers the process that will get all chunks from PDF into our strategy Object
string currentText = PdfTextExtractor.GetTextFromPage(pReader, page, strategy);
//The real getter process starts in the following line
List<iTextSharp.text.Rectangle> MatchesFound = strategy.GetTextLocations(pSearch, SC);
//Set the fill color of the shapes, I don't use a border because it would make the rect bigger
//but maybe using a thin border could be a solution if you see the currect rect is not big enough to cover all the text it should cover
cb.SetColorFill(BaseColor.WHITE);
//MatchesFound contains all text with locations, so do whatever you want with it, this highlights them using PINK color:
foreach (iTextSharp.text.Rectangle rect in MatchesFound)
{
//width
cb.Rectangle(rect.Left, rect.Bottom, 60, rect.Height);
cb.Fill();
cb2.SetColorFill(BaseColor.BLACK);
bf = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb2.SetFontAndSize(bf, 9);
cb2.BeginText();
cb2.ShowTextAligned(0, replacingText, rect.Left, rect.Bottom, 0);
cb2.EndText();
cb2.Fill();
}
}
}
}
catch (Exception ex)
{
}
}
}
}