Replace function ( InsertValueAtReplaceHandler) replaces the whole line of document

Hello,

I am converting a docx to pdf using ASPOSE where I have a predefined docx template. Template has document heading and some tokens. I am replacing those tokens by it’s value using replace function. Here I am facing 3 different issues listed below,

  1. Template header has some text and token. When I try to replace the token with value, that value replaces whole line of header (i.e. replaces text plus token. where the expected result must be text + replaced token value)
  2. Template has two tokens on same line which is separated by dash (-) symbol. Both token has different value however prefix of both token is same. This gives a inappropriate result after replace.
  3. Template has table and table cell has a rich text data. That rich text is present in some other docx file and I am merging the parent document which has table and other document which has rich text ( table cell values). In this scenario rich text is getting merged properly under respective columns but it affects on watermark. The replaced rich text hide its background watermark.

could you please provide me the root cause of these issues and workaround too.
Thanks!

@vke3,

Thanks for your inquiry. To ensure a timely and accurate response, please attach the following resources here for testing:

  • Your input Word document.
  • Please attach the output Word file that shows the undesired behavior.
  • Please create a simple Java application (source code without compilation errors) that helps us to reproduce your problem on our end and attach it here for testing.

As soon as you get these pieces of information ready, we’ll start investigation into your issue and provide you more information. Thanks for your cooperation.

PS: To attach these resources, please zip and upload them.

PDF Generation Issue Demo files.zip (252.0 KB)

Please find the attached zip file for your reference.
Thank you.

@vke3,

Thanks for sharing the detail. In your case, we suggest you please use Rnage.Replace method as shown below.

Document doc = new Document(MyDir + "input.docx");

doc.getRange().replace("${program:MyDemo.getDate}", "11/05/2018", new FindReplaceOptions());
doc.getRange().replace("${selectable: name}", "name value", new FindReplaceOptions());

doc.save(MyDir + "out.docx");

If you want to implement IReplacingCallback, we suggest you please use the approach shared in following article.
How to Find and Highlight Text

Please check the following code snippet. At the end of this method, you need to move the cursor to the desired location, insert the content, and remove the Run nodes.

public int replacing(ReplacingArgs e) throws Exception {

            // This is a Run node that contains either the beginning or the complete match.
            Node currentNode = e.getMatchNode();
            // The first (and may be the only) run can contain text before the match,
            // in this case it is necessary to split the run.
            if (e.getMatchOffset() > 0)
                currentNode = splitRun((Run) currentNode, e.getMatchOffset());

            ArrayList runs = new ArrayList();

            // Find all runs that contain parts of the match string.
            int remainingLength = e.getMatch().group().length();
            while ((remainingLength > 0) && (currentNode != null) && (currentNode.getText().length() <= remainingLength)) {
                runs.add(currentNode);
                remainingLength = remainingLength - currentNode.getText().length();
                // Select the next Run node.
                // Have to loop because there could be other nodes such as BookmarkStart etc.
                do {
                    currentNode = currentNode.getNextSibling();
                } while ((currentNode != null) && (currentNode.getNodeType() != NodeType.RUN));
            }

            // Split the last run that contains the match if there is any text left.
            if ((currentNode != null) && (remainingLength > 0)) {
                splitRun((Run) currentNode, remainingLength);
                runs.add(currentNode);
            }

            DocumentBuilder builder = new DocumentBuilder((Document)e.getMatchNode().getDocument());
            builder.moveTo((Run)runs.get(0));

	    // Your code to insert the content

            // Remove matched text
            for (Run run : (Iterable<Run>) runs)
                run.remove();

            // Signal to the replace engine to do nothing because we have already done all what we wanted.
            return ReplaceAction.SKIP;

        }

@tahir.manzoor

It works :slight_smile:
My first two issues gets resolved. Thank you so much for your support.
Could you please comment on 3rd issue i.e the watermark issue?
My rich text override watermarks ( mostly in scenario where I am inserting one document rich text in my another parent document in table cell).

@vke3,

Thanks for your inquiry. Please use following code example to insert watermark on each page of document. Hope this helps you.

public static void InsertWatermarkImageAtEachPage (Document doc, String watermarkImagePath) throws Exception
{
    DocumentBuilder builder = new DocumentBuilder(doc);

    LayoutCollector collector = new LayoutCollector(doc);

    int pageIndex = 1;
    for (Section section : doc.getSections())
    {
        NodeCollection paragraphs = section.getBody().getChildNodes(NodeType.PARAGRAPH, true);
        for(Paragraph para : (Iterable<Paragraph>)paragraphs)
        {
            if (collector.getStartPageIndex(para) == pageIndex)
            {
                builder.moveToParagraph(paragraphs.indexOf(para), 0);
                builder.startBookmark("BM_Page" + pageIndex);
                builder.endBookmark("BM_Page" + pageIndex);
                pageIndex++;
            }
        }
    }

    collector = new LayoutCollector(doc);
    LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);

    int PageRelativeY = 0;
    int PageRelativeX = 0;

    for (Bookmark bookmark : doc.getRange().getBookmarks())
    {
        if (bookmark.getName().startsWith("BM_"))
        {
            Paragraph para = (Paragraph)bookmark.getBookmarkStart().getParentNode();

            Shape watermark = new Shape(doc, ShapeType.IMAGE);

            watermark.setTop(PageRelativeY);
            watermark.setLeft(PageRelativeX);

            watermark.getImageData().setImage(watermarkImagePath);
            //Set the width height according to your requirements
            watermark.setWidth(470);
            watermark.setHeight(625);
            watermark.setBehindText(true);

            para.appendChild(watermark);

            watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
            watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);

            Boolean isInCell = bookmark.getBookmarkStart().getAncestor(NodeType.CELL) != null;
            if (isInCell)
            {
                Object renderObject = collector.getEntity(bookmark.getBookmarkStart());
                layoutEnumerator.setCurrent(renderObject);

                layoutEnumerator.moveParent(LayoutEntityType.CELL);

                watermark.setTop(PageRelativeY - layoutEnumerator.getRectangle().getY());
                watermark.setLeft(PageRelativeX - layoutEnumerator.getRectangle().getX());
            }
        }
    }
}

@tahir.manzoor,

Tried your fix too however it won’t work. Inserted document still override the watermark.

@vke3,

Thanks for your inquiry. To ensure a timely and accurate response, please attach the following resources here for testing:

  • Your input Word document.
  • Please attach the output Word file that shows the undesired behavior.
  • Please create a standalone console application (source code without compilation errors) that helps us to reproduce your problem on our end and attach it here for testing.

As soon as you get these pieces of information ready, we’ll start investigation into your issue and provide you more information. Thanks for your cooperation.

PS: To attach these resources, please zip and upload them.

@tahir.manzoor,

I have already shared the input and output documents. Below is the code snippet used for watermark
public static void insertWatermarkText(Document doc, String watermarkText) throws Exception {
Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT);

	watermark.getTextPath().setText(watermarkText);
	watermark.getTextPath().setFontFamily("Arial");
	watermark.setWidth(500);
	watermark.setHeight(100);
	watermark.setRotation(-40);
	watermark.getFill().setColor(Color.LIGHT_GRAY); // Try LightGray to get more Word-style watermark
	watermark.setStrokeColor(Color.LIGHT_GRAY); // Try LightGray to get more Word-style watermark

	watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
	watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
	watermark.setWrapType(WrapType.NONE);
	watermark.setVerticalAlignment(VerticalAlignment.CENTER);
	watermark.setHorizontalAlignment(HorizontalAlignment.CENTER);

	Paragraph watermarkPara = new Paragraph(doc);
	watermarkPara.appendChild(watermark);

	for (Section sect : doc.getSections()) {
		insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);
		insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_FIRST);
		insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_EVEN);
	}
}

protected static void insertWatermarkIntoHeader(Paragraph watermarkPara, Section sect, int headerType) throws Exception {
	HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType);

	if (header == null) {
		header = new HeaderFooter(sect.getDocument(), headerType);
		sect.getHeadersFooters().add(header);
	}
            header.appendChild(watermarkPara.deepClone(true));
} 
Summary

Below is the code I use for inserting rich text to table cell

private void addRichTextToTableCell(Context context, String sObjectId, Cell cell, Paragraph paragraph, String sRTEAttribute)
throws Exception, FileNotFoundException {
File richTextFile = RichTextEditOnlineUtils.getRichTextFile(context, sObjectId, sRTEAttribute);
if(!richTextFile.exists()){
throw new FileNotFoundException();
}
Document document = new Document(new FileInputStream(richTextFile));
if ((paragraph.getNodeType() != NodeType.PARAGRAPH) & (paragraph.getNodeType() != NodeType.TABLE))
throw new IllegalArgumentException(“The destination node should be either a paragraph or table.”);
CompositeNode cNode = paragraph.getParentNode();
NodeImporter importer = new NodeImporter(document, paragraph.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING);
for (Section sSection : document.getSections()) {
for (Node documentNode : (Iterable) sSection.getBody()) {
if (documentNode.getNodeType() == (NodeType.PARAGRAPH)) {
Paragraph para = (Paragraph) documentNode;
if (para.isEndOfSection() && !para.hasChildNodes())
continue;
}
Node newNode = importer.importNode(documentNode, true);
cNode.insertAfter(newNode, paragraph);
paragraph = (Paragraph) newNode;
}
}
}

@vke3,

Thanks for your inquiry. Your input Word document has only one page. Please generate your final output DOCX. Before saving the document, please call InsertWatermarkImageAtEachPage method shared here.

If you still face problem, please create a simple Java application (source code without compilation errors) that helps us to generate the output DOCX. We will investigate the issue and provide you more information on this issue.

@tahir.manzoor,

Could you please check “Watermark Issue.JPG” image which I had shared, to check the problem of watermark. I can’t share you the whole document according to some policies. So just send you the image of one page.

@tahir.manzoor,

Yes, we checked this image. The InsertWatermarkImageAtEachPage will solve this issue. You need to call this method before saving the document.

:frowning: Tried this approach and its still not working. Same problem is there with watermark.

@vke3,

Thanks for your inquiry. To ensure a timely and accurate response, please create a simple Java application (source code without compilation errors) that helps us to generate the output DOCX.

We will investigate the issue and provide you modified code example that will insert the watermark in the document. if you cannot supply us with this information we will not be able to investigate your issue. Thanks for your cooperation.

Hi,

I have some indentation issue as well in PDF generation. It add a lot of space when I tried to insert document. you can check my attached output.pdf file for that. I tried many combinations it doesn’t work. below things I tried,
doc.getCompatibilityOptions().setSuppressSpBfAfterPgBrk(true);
doc.getCompatibilityOptions().setSplitPgBreakAndParaMark(false); doc.getCompatibilityOptions().setDoNotUseHTMLParagraphAutoSpacing(true);
doc.getCompatibilityOptions().setSuppressBottomSpacing(true);
doc.getCompatibilityOptions().setSuppressTopSpacing(true);
doc.getCompatibilityOptions().setSuppressTopSpacingWP(true);

if(paragraph.getParagraphFormat().getSpaceAfterAuto()==true){
paragraph.getParagraphFormat().setSpaceAfterAuto(false);
paragraph.getParagraphFormat().setSpaceAfter(0);
}else if(paragraph.getParagraphFormat().getSpaceBeforeAuto()==true){
paragraph.getParagraphFormat().setSpaceBeforeAuto(false);
paragraph.getParagraphFormat().setSpaceBefore(0);
}

could you please look into it.

@vke3,

Thanks for your inquiry. Please call Document.UpdatePageLayout method before saving the document to PDF. Hope this helps you.

@tahir.manzoor,

Document.UpdatePageLayout also won’t work :frowning:

@vke3,

Thanks for your inquiry. To ensure a timely and accurate response, please attach the following resources here for testing:

  • Your input Word document. If you are using same input document that you shared in this thread, no need to share it.
  • Please attach the expected output Word/PDF file that shows the desired behavior.
  • Please create a simple Java application (source code without compilation errors) that helps us to reproduce your problem on our end and attach it here for testing.

As soon as you get these pieces of information ready, we’ll start investigation into your issue and provide you more information. Thanks for your cooperation.

PS: To attach these resources, please zip and upload them.

@tahir.manzoor,

Hi,

Sharing the input files and expected output file along with some screenshot of output which I get.
Code snippet is not shared. you can refer the approach I have used in code which I already shared with you.
Thank you.

Summary

Demo Files.zip (83.6 KB)

@vke3,

Thanks for sharing the documents. We have tested the scenario using latest version of Aspose.Words for Java 18.6 with following code example. We have not found any issue with output document. Please check the attached output PDF.18.6.pdf (64.1 KB)

We suggest you please do not use CompatibilityOptions.DoNotUseHTMLParagraphAutoSpacing in your code. Hope this helps you.

Document doc = new Document(MyDir + "Input.docx");

doc.getCompatibilityOptions().setSuppressSpBfAfterPgBrk(true);
doc.getCompatibilityOptions().setSplitPgBreakAndParaMark(false);
doc.getCompatibilityOptions().setSuppressBottomSpacing(true);
doc.getCompatibilityOptions().setSuppressTopSpacing(true);
doc.getCompatibilityOptions().setSuppressTopSpacingWP(true);

InsertWatermarkTextAtEachPage(doc, "Draft");
doc.updatePageLayout();

doc.save(MyDir + "18.6 getCompatibilityOptions.pdf");

public static void InsertWatermarkTextAtEachPage (Document doc, String watermarkText) throws Exception
{
    DocumentBuilder builder = new DocumentBuilder(doc);
    LayoutCollector collector = new LayoutCollector(doc);

    int pageIndex = 1;
    for (Section section : doc.getSections())
    {
        NodeCollection paragraphs = section.getBody().getChildNodes(NodeType.PARAGRAPH, true);
        for(Paragraph para : (Iterable<Paragraph>)paragraphs)
        {
            if (collector.getStartPageIndex(para) == pageIndex)
            {
                builder.moveToParagraph(paragraphs.indexOf(para), 0);
                builder.startBookmark("BM_Page" + pageIndex);
                builder.endBookmark("BM_Page" + pageIndex);
                pageIndex++;
            }
        }
    }

    int PageRelativeY = 50;
    int PageRelativeX = 50;

    for (Bookmark bookmark : doc.getRange().getBookmarks())
    {
        if (bookmark.getName().startsWith("BM_"))
        {
            Paragraph para = (Paragraph)bookmark.getBookmarkStart().getParentNode();

            Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT);

            watermark.setTop(PageRelativeY);
            watermark.setLeft(PageRelativeX);
            watermark.getTextPath().setText(watermarkText);

            watermark.getTextPath().setFontFamily("Arial");
            watermark.setWidth(500);
            watermark.setHeight(100);
            watermark.setRotation(-40);
            watermark.getFill().setColor(Color.LIGHT_GRAY); // Try LightGray to get more Word-style watermark
            watermark.setStrokeColor(Color.LIGHT_GRAY); // Try LightGray to get more Word-style watermark

            watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
            watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
            watermark.setWrapType(WrapType.NONE);
            watermark.setVerticalAlignment(VerticalAlignment.CENTER);
            watermark.setHorizontalAlignment(HorizontalAlignment.CENTER);

            para.appendChild(watermark);
        }
    }
}