Retain Text position alignment while replacing Text in PDF

Hello Farhan,

Tried with the given code changes but somehow its not solve problem.
The alignment for pdf still get disturb for stamping.
Please let me know if any input needed or we can set up meeting.

Thanks
Vivek

@vsgardi

Thank you for getting back to us.

Please note that support is offered via forums only. Moreover, we have attached the PDF documents generated with Aspose.PDF for Java 19.2 so would you please list down the differences or highlight the problems so that we may further address your concerns.

Hi,

I am not able to download these pdf attached here.

Thanks,
Vivek

@vsgardi

Forum attachments are accessible to thread owner and Aspose staff only. So you may download the files from Google Drive and then share your kind feedback with us. Moreover, please upgrade to Aspose.PDF for Java 19.3 in your environment.

Hello Aspose,

I tried with your suggested changes in replace function. But for our input file issue not getting solve. It only stamp or replace keyword on 1st page correctly but 2nd page onward it disturbs.
1st page -
image.png (3.2 KB)
2nd page onward-
image.png (3.7 KB)
Also attached code-
updated_code.zip (19.0 KB)

Please let me know if any input needed.

Thanks,
Vivek

@vsgardi

Thank you for sharing the details.

The files you had shared with us previously only contain single page but the issue you are referring to now looks to be appearing with some other PDF documents. Would you please create a separate topic while sharing all details including source files, generated files, code snippet and screenshots so that we may check all the details and investigate further to help you out.

Hello,

Is there any update on “PDFJAVA-37650” this ticket?

Thanks,
Vivek

@vsgardi

Thank you for getting back to us.

We would like to update you that PDFJAVA-37650 has been closed and the problem with text rotation has been fixed. Please note that when changing font on the TextFragment level the algorithm is taking into account font style, metrics, size, margins and other text fragments on the page.It can prevent to changing position and wrapping because this is complex element and can inter-operate with other objects and parameters. To keep all the places when just changing the font we should change font on the TextSegment level.
We can get all the TextSegments from the TextFragment using the following line:

textFragment.getSegments()

The following code works fine:

package asposeforum;

import static asposeforum.AsposeForum.readFileContents;
import com.aspose.pdf.Color;
import com.aspose.pdf.Document;
import com.aspose.pdf.FileEncoding;
import com.aspose.pdf.FileSpecification;
import com.aspose.pdf.Font;
import com.aspose.pdf.FontRepository;
import com.aspose.pdf.FontSource;
import com.aspose.pdf.HorizontalAlignment;
import com.aspose.pdf.LoadOptions;
import com.aspose.pdf.Page;
import com.aspose.pdf.PageCollection;
import com.aspose.pdf.TabStops;
import com.aspose.pdf.TextAbsorber;
import com.aspose.pdf.TextFormattingOptions;
import com.aspose.pdf.TextFragment;
import com.aspose.pdf.TextFragmentAbsorber;
import com.aspose.pdf.TextFragmentCollection;
import com.aspose.pdf.TextReplaceOptions;
import com.aspose.pdf.TextSearchOptions;
import com.aspose.pdf.TextStamp;
import com.aspose.pdf.VerticalAlignment;
import com.aspose.pdf.facades.PdfContentEditor;
import com.aspose.pdf.text.FontSourceCollection;
import static com.sun.org.apache.bcel.internal.classfile.Utility.replace;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import sun.net.dns.ResolverConfiguration.Options;

public class CustomStamping {

    public static Document pdfInputDocument;

public CustomStamping() 
{
}
/**
 * @param args
 * @throws IOException 
 */
public static void main(String[] args) throws IOException {

    System.out.println("Execution Details");
    System.out.println("*****************");
    System.out.println("USER::"+System.getProperty("user.name"));
    try {
        java.net.InetAddress localMachine = java.net.InetAddress.getLocalHost();
        System.out.println("HOSTNAME::" + localMachine.getHostName());
    } catch (UnknownHostException e1) {
        e1.printStackTrace();
    }
    System.out.println("START TIME::"+new Date());
    System.out.println("");
// try 
{
// cmd = parser.parse(options, args);
}
// catch (ParseException e)
{
// System.out.println("Error:: "+e.getMessage());
// formatter.printHelp("Custom Stamping", options);
// System.exit(1);
// return;
}
// System.out.println("Arguments");
// System.out.println("******");
// for(Option option : cmd.getOptions()) {
// System.out.println("\t"+option.getOpt()+"["+option.getDescription()+"] is "+option.getValue());
// }
System.out.println("*************");
System.out.println("End of Arguments");
System.out.println("");

    System.out.println("Setting License");
    System.out.println("***************");
    boolean isLicensed=initializeAspose();
    if(isLicensed)
    {
        System.out.println("\t"+"Succesfully Set License");
    }
    else
    {
        System.out.println("\t"+"Error:: Setting License");
    }
    System.out.println("End of Setting License");
    System.out.println("**********************");
    System.out.println("");

    String strInputPath = "D:\\input_retain.pdf";// cmd.getOptionValue("i");
    String strOutputPath = "D:\\Aspose.PDF_18.3.pdf";//cmd.getOptionValue("o");
    String strKeyFile = "D:\\KeyWordsCustomStamping.txt";// cmd.getOptionValue("k");
    String strValueFile = "D:\\StampResult_xrepd51ho6iujA.txt";// cmd.getOptionValue("v");
    String strIsPreviewFile = "true";// cmd.getOptionValue("p");
    String strWrapNeded= "false";//cmd.getOptionValue("wrap");
    String strDefaultFont= "Arial";//cmd.getOptionValue("defaultFont");
    File fileOutputPath = new File(strOutputPath);
    File fileInputPath = new File(strInputPath);
    if (!fileInputPath.exists())
    {
        System.out.println("Error:: "+ "File ["+fileInputPath+"] not found");
        return;
    }
    File fileKeyFile = new File(strKeyFile);
    if (!fileKeyFile.exists())
    {
        System.out.println("Error:: "+ "File ["+fileKeyFile+"] not found");
        return;
    }
    File fileValueFile = new File(strValueFile);
    if (!fileValueFile.exists())
    {
        System.out.println("Error:: "+ "File ["+fileValueFile+"] not found");
        return;
    }

    pdfInputDocument = new Document(strInputPath);
    ArrayList<String> keyFileContents = readFileContents(strKeyFile, "::");
    ArrayList<String> valueFileContents = readFileContents(strValueFile, "::");
    Map<String, String> mKeys = new HashMap<String, String>();
    Map<String, String> mValues = new HashMap<String, String>();
    System.out.println("Reading Key File Contents");
    System.out.println("*************************");
    for (String string : keyFileContents)
    {
        System.out.println("Input Line ::"+string);
        String[] splittedStrings = string.split(" ", -1);
        if(splittedStrings.length==2)
        {
            mKeys.put(splittedStrings[0], splittedStrings[1].replaceAll("^\"|\"$", ""));
            System.out.println("\tKey="+splittedStrings[0]+" Value="+splittedStrings[1].replaceAll("^\"|\"$", ""));
        }
    }
    System.out.println("********************************");
    System.out.println("End of Reading Key File Contents");
    System.out.println("");
    System.out.println("Reading Value File Contents");
    System.out.println("***************************");
    for (String string : valueFileContents)
    {
        System.out.println("Input Line ::"+string);
        String[] splittedStrings = string.split(" ", -1);
        if(splittedStrings.length==2)
        {
            mValues.put(splittedStrings[0].replaceAll("^\"|\"$", ""), splittedStrings[1].replaceAll("^\"|\"$", ""));
            System.out.println("\tKey="+splittedStrings[0].replaceAll("^\"|\"$", "")+" Value="+splittedStrings[1].replaceAll("^\"|\"$", ""));
        }
        if(splittedStrings.length>2)
        {
            String temp="";
            for (int i1=1; i1<splittedStrings.length; i1++)
            {
                temp += splittedStrings[i1];
                temp += " ";
            }
            temp=temp.trim();
            mValues.put(splittedStrings[0].replaceAll("^\"|\"$", ""), temp.replaceAll("^\"|\"$", ""));
            System.out.println("\tKey="+splittedStrings[0].replaceAll("^\"|\"$", "")+" Value="+temp.replaceAll("^\"|\"$", ""));
        }
    }
    System.out.println("******************************");
    System.out.println("End of Value Key File Contents");
    System.out.println("");     
    System.out.println("Starting to Replace Fonts in PDF File");
    System.out.println("***********************************");

    /****************************Font Reset**************************************/      
    TextFragmentAbsorber absorberFontChanger = new TextFragmentAbsorber(new com.aspose.pdf.TextEditOptions(com.aspose.pdf.TextEditOptions.FontReplace.RemoveUnusedFonts));
    pdfInputDocument.getPages().accept(absorberFontChanger);
    TextFragmentCollection textFragmentCollection2 = absorberFontChanger.getTextFragments();
    for (Iterator<TextFragment> iterator = textFragmentCollection2.iterator(); iterator.hasNext();)
    {
        TextFragment textFragment = iterator.next();
        String textFont=textFragment.getTextState().getFont().getFontName();
        System.out.println("Text:: "+textFragment.getText()+" Font::"+textFont);
        Font fontRepo = null;
        try {
            fontRepo = FontRepository.findFont(textFont);
        } catch (Exception e) {

        }
        if(fontRepo!=null)
        {
            System.out.println("\t"+"Replacing with System Font ::"+textFont);
// textFragment.getTextState().setFont(fontRepo);
for (Iterator iterator_s = textFragment.getSegments().iterator(); iterator_s.hasNext(); )
{
TextSegment textSegment = iterator_s.next();
textSegment.getTextState().setFont(fontRepo);
}
}else{

            System.out.println("\t"+"Info:: Font Not Found in system ::"+textFont);
            System.out.println("\t"+"Info:: Replacing with default font ::"+strDefaultFont);                
            Font fontRepo1 = null;
            try {
                fontRepo1 = FontRepository.findFont(strDefaultFont);
            } catch (Exception e) {

            }
            if(fontRepo1!=null)
            {
                System.out.println("\t"+"Replacing with Default Font ::"+strDefaultFont);
// textFragment.getTextState().setFont(fontRepo1);
for (Iterator iterator_s = textFragment.getSegments().iterator(); iterator_s.hasNext(); )
{
TextSegment textSegment = iterator_s.next();
textSegment.getTextState().setFont(fontRepo1);
}
} else
{
System.out.println("\t"+"Info:: Default Font Not Found in system ::"+strDefaultFont);
System.out.println("\t"+"Info:: Replacing with System default font ::Arial");

Font fontRepo2 = null;
try {
fontRepo2 = FontRepository.findFont("Arial");
} catch (Exception e) {

                }
                if(fontRepo2!=null)
                {
                    System.out.println("\t"+"Replacing with System Default Font ::Arial");
// textFragment.getTextState().setFont(fontRepo2);
for (Iterator iterator_s = textFragment.getSegments().iterator(); iterator_s.hasNext(); )
{
TextSegment textSegment = iterator_s.next();
textSegment.getTextState().setFont(fontRepo2);
}

                } else
                {
                    System.out.println("\t"+"Error:: Default System Font[Arial] Not Found in system");
                }
            }
        }
    }
    /******************************************************************/
    System.out.println("******************************");
    System.out.println("End of Replace Fonts in PDF File");
    System.out.println("");     
    System.out.println("Starting to Replace key in PDF File");
    System.out.println("***********************************");
    for (Entry<String, String> keyEntry : mKeys.entrySet()) 
    {
        String strKey=keyEntry.getKey();
        String strValue="";
        if(mValues.containsKey(keyEntry.getValue()))
        {
            strValue=mValues.get(keyEntry.getValue());
        }
        //System.out.println("Replacing key "+strKey+" with value "+strValue);
        replace( strKey, strValue,strWrapNeded);
    }
    System.out.println("******************************");
    System.out.println("End of Replace key in PDF File");
    System.out.println("");
// if(strIsPreviewFile.equalsIgnoreCase("true"))
{
System.out.println("Adding Preview stamp, since p is set to true");
// stampPreiew();
}
// else
{
System.out.println("No Preview stamp is added, since p is set to false");
}
System.out.println("");

try {
System.out.println("Trying to save File to "+strOutputPath);
pdfInputDocument.setEmbedStandardFonts(true);
pdfInputDocument.save(strOutputPath);
System.out.println("Saved File to "+strOutputPath);

} catch (Exception e) {
System.out.println("Error saving File to "+strOutputPath);
System.out.println("Error:: "+e.getMessage());
e.printStackTrace();
}
System.out.println("");
System.out.println("END TIME::"+new Date());
System.out.println("Completed!!!");
}
private static boolean initializeAspose()
{

// String strAsposeLicense=System.getenv("ASPOSE_LICENSE");
// if(strAsposeLicense==null || strAsposeLicense.isEmpty())
{
// System.out.println("\t"+"Error:: Unable to find System Variable \"ASPOSE_LICENSE\" or the value is empty");

// return false;
// }else
{
com.aspose.pdf.License license = new com.aspose.pdf.License();
try 
{
//license.setLicense(new java.io.FileInputStream("D:\Licenses\Aspose.Total.Java.lic"));
license.setLicense("D:\Licenses\Aspose.Total.Java.lic");

            if (com.aspose.pdf.Document.isLicensed())
            {
                System.out.println("License is Set!");
                return true;
            }else{
                return false;
            }


        } catch (Exception e)
        {
            //e.printStackTrace();
            System.out.println("\t"+"Error:: "+e.getMessage());
            System.out.println("\t"+"Error:: Unable to set License from System Variable\"ASPOSE_LICENSE\"");
            return false;
        }       
    }
}}

In case you notice any issue while using Aspose.PDF for Java 19.4 then feel free to contact us for further assistance.