How to get current position of the DocumentBuilder


#1

Hello, how do we get the current position of the DocumentBuilder?
For example, we have a standard letter page size of 8.5 inches wide.
If the DocumentBuilder is in the middle of the page, it’s position is 4.25.

Also, is there a way to measure the width of a string when printed in the document?

Our requirement is to print answers on a given template document. but if the answer exceeds the allocated space for it, we need to just print “SEE ATTACHED”.

Thank you,
Jan


#2

@gojanpaolo,

You can calculate the (x,y) coordinates of any string in Word document by using the following code:

private class MyReplaceEvaluator : IReplacingCallback
{
    ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
    {
        DocumentBuilder builder = new DocumentBuilder((Document)e.MatchNode.Document);
        builder.MoveTo(e.MatchNode);

        BookmarkStart start = builder.StartBookmark("temp");
        builder.EndBookmark("temp");

        LayoutCollector collector = new LayoutCollector((Document)e.MatchNode.Document);
        LayoutEnumerator enumerator = new LayoutEnumerator((Document)e.MatchNode.Document);

        enumerator.Current = collector.GetEntity(start);
        // 72 points are equal to 1 inch
        Console.WriteLine("({0}, {1})", enumerator.Rectangle.Left, enumerator.Rectangle.Top);
        e.MatchNode.Document.Range.Bookmarks["temp"].Remove();
        return ReplaceAction.Skip;
    }
}

Document doc = new Document("E:\\Temp\\in.docx");

FindReplaceOptions opts = new FindReplaceOptions();
opts.Direction = FindReplaceDirection.Backward;
opts.ReplacingCallback = new MyReplaceEvaluator();

doc.Range.Replace(new Regex("FIND MY COORDIANTES"), "", opts);

But, width of string in Word document is a relative term. For example, what if string spans across multiple lines? Anyway, I think, you can obtain the positions of any node(s) by using the classes of Aspose.Words.Layout Namespace (see LayoutEnumerator.Rectangle property).


#3

Hello @awais.hafeez, thanks for the immediate response.
We need to calculate the width of the string before it gets written to the document.
consider the following code

DocumentBuilder builder;
int maxWidth;
string text = "this is a very long string";
if(builder.MeasureWidth(text) > maxWidth)
{
    builder.Write("SEE ATTACHED");
}
else
{
    builder.Write(text);
}

As for strings spanning multiple lines, we can just have a higher max width value. e.g. if one whole line is 8.5 inches and assuming 0 margin, then we can have a max width of 17 inches for strings that can span at most 2 lines.


#4

@gojanpaolo,

I think, you can meet this requirement by using the following code;

// You cannot measure width of string unless you write it inside a temporary document
Document tempDoc = new Document();
DocumentBuilder builder = new DocumentBuilder(tempDoc);

PageSetup ps = tempDoc.FirstSection.PageSetup;
ps.PageWidth = 22 * 72; // Max allowed page width in MS Word
ps.PageHeight = 22 * 72; // Max allowed page height in MS Word
ps.LeftMargin = ps.TopMargin = ps.RightMargin = ps.BottomMargin = 0;

// Aspose.Words 19.11 by default uses Times New Roman font and 12 points font size
builder.CurrentParagraph.ParagraphBreakFont.Size = 1;
builder.Writeln("this is a very long string");

// Lets write another string with different formatting
builder.Font.Name = "Verdana";
builder.Font.Size = 20;
builder.CurrentParagraph.ParagraphBreakFont.Size = 1;
builder.Writeln("this is a very long string");

// Now that the strings are written inside temporary document
// lets calculate what would be their widths            
LayoutCollector collector = new LayoutCollector(tempDoc);
LayoutEnumerator enumerator = new LayoutEnumerator(tempDoc);

enumerator.Current = collector.GetEntity(tempDoc.FirstSection.Body.Paragraphs[0]);
// 72 points are equal to 1 inch
Console.WriteLine("Width of this string is {0} points or {1} inches",
    enumerator.Rectangle.Right,
    ConvertUtil.PointToInch(enumerator.Rectangle.Right));

enumerator.Current = collector.GetEntity(tempDoc.FirstSection.Body.Paragraphs[1]);
// 72 points are equal to 1 inch
Console.WriteLine("Width of this string is {0} points or {1} inches",
    enumerator.Rectangle.Right,
    ConvertUtil.PointToInch(enumerator.Rectangle.Right));

// Just saving to see how the string look like in temporary document
tempDoc.Save("E:\\Temp\\19.11.docx");

// Now in your original document, you can make decision based on above Width values
...
...