Aspose.Words, Right Justified Vertical Bar with Rotated text

Hello, I am looking for some help with a small function. Given a one page Word Document (A Book Cover) I want to paint a vertical bar on the far right of the page from top bottom with text that is rotated and centered.

This is a C# function and takes the inputs

width = width of bar
Text = The text that is in the bar (the rotated part)
from top = gutter amount from top (points). I need a little space above bar
from bottom = gutter amount from top (points). I need a little space below bar
from right = gutter amount from right (points). I need a little space to the right of the bar and right side of page.

Thanks in advance and anything will help.

@adventurousbooks

Thanks for your inquiry. Please use the following code example to get the desired output. Hope this helps you.

If you still face problem, please manually create your expected Word document using Microsoft Word and attach it here for our reference. We will investigate how you want your final Word output be generated like. We will then provide you more information on this along with code.

Document doc = new Document();
Aspose.Words.Drawing.Shape watermark = new Aspose.Words.Drawing.Shape(doc, Aspose.Words.Drawing.ShapeType.Rectangle);

watermark.Width = 200;
watermark.Height = doc.FirstSection.PageSetup.PageHeight;
watermark.Fill.Color = Color.Gray;  
watermark.StrokeColor = Color.Gray;  

// Place the watermark in the page center.
watermark.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
watermark.RelativeVerticalPosition = RelativeVerticalPosition.Page;
watermark.WrapType = WrapType.None;
watermark.VerticalAlignment = VerticalAlignment.Top;
watermark.HorizontalAlignment = HorizontalAlignment.Right;

doc.FirstSection.Body.FirstParagraph.AppendChild(watermark);

Paragraph text = new Paragraph(doc);
text.AppendChild(new Run(doc, "Book Cover Text"));
text.Runs[0].Font.Size = 25;
watermark.AppendChild(text);
watermark.TextBox.LayoutFlow = LayoutFlow.TopToBottom;

doc.Save(MyDir + "output.docx");

Thank You Tahir,
This really helps a lot, but I am looking for something a little different and I can’t get the result. I have attached a pdf file as an example:

test.pdf (54.1 KB)

@adventurousbooks

Thanks for your inquiry. We have modified the code according to your requirement. Hope this helps you.

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Aspose.Words.Drawing.Shape watermark = new Aspose.Words.Drawing.Shape(doc, Aspose.Words.Drawing.ShapeType.Rectangle);

watermark.Width = 50;
watermark.Height = doc.FirstSection.PageSetup.PageHeight - 40;
watermark.Fill.Color = Color.Gray;
watermark.StrokeColor = Color.Gray;

// Place the watermark in the page center.
watermark.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
watermark.RelativeVerticalPosition = RelativeVerticalPosition.Page;
watermark.WrapType = WrapType.None;
watermark.Left = doc.FirstSection.PageSetup.PageWidth - watermark.Width - 20;
watermark.Top = 20;

doc.FirstSection.Body.FirstParagraph.AppendChild(watermark);

Paragraph text = new Paragraph(doc);
text.ParagraphFormat.Alignment = ParagraphAlignment.Center;
watermark.AppendChild(text);
watermark.TextBox.LayoutFlow = LayoutFlow.TopToBottom;

builder.MoveTo(text);
builder.Font.Size = 25;
builder.Font.Color = Color.Yellow;
builder.Write("Hello : ");
builder.Font.Color = Color.Violet;
builder.Write("Jane Does");

doc.Save(MyDir + "19.2.docx");
doc.Save(MyDir + "19.2.pdf");

Great! The logic is what I need unfortunately I am using classic ASP with a ComWrapper. I need to take what you have above and transform into a ComWrapper. Below is my feeble attempt that fails. I know my programming is way off for a ComWrapper. Doing the best I can. Can you help me?

public void BookCover_InsertStepTab( object docSource, object b )
{
DocumentBuilder builder = (DocumentBuilder)b;
Document d = (Document)docSource;

        double widthInPoints = 50;
        double topInPoints = 20;

        double leftInPoints =  builder.FirstSection.PageSetup.PageWidth - 50 - 20;
        double heightInPoints = builder.FirstSection.PageSetup.PageHeight - 40;

        Shape stepTab = builder.InsertShape(ShapeType.Rectangle,
                              RelativeHorizontalPosition.Page, leftInPoints,
                              RelativeVerticalPosition.Page, topInPoints,
                              widthInPoints, heightInPoints,
                              WrapType.None);
         
        Run run1 = new Run(d, "Hello : ");
        run1.Font.Name = "Arial";
        run1.Font.Italic = true;
        run1.Font.Size = 25;
        run1.Font.Color = Color.Yellow;

        stepTab.FirstParagraph.AppendChild( run1 );

        Run run2 = new Run(d, "Jane Doe ");
        run2.Font.Name = "Arial";
        run2.Font.Italic = true;
        run2.Font.Size = 25;
        run2.Font.Color = Color.Violet;

        stepTab.FirstParagraph.AppendChild( run2 );

        stepTab.TextBox.LayoutFlow = LayoutFlow.TopToBottom;
        stepTab.FillColor = Color.FromArgb( 0, 0, 0);

    }

@adventurousbooks

Thanks for your inquiry.

Please use Document object instead of DocumentBuilder object as shown in following two lines.

double leftInPoints = d.FirstSection.PageSetup.PageWidth - 50 - 20;
double heightInPoints = d.FirstSection.PageSetup.PageHeight - 40;

Thank You tahir,

I have the placement and display of the rectangle. All good! For some reason the displaying of the text is causing problems. I think this section may cause problems:

    Run run1 = new Run(d, "Hello : ");
    run1.Font.Name = "Arial";
    run1.Font.Italic = true;
    run1.Font.Size = 25;
    run1.Font.Color = Color.Yellow;

    stepTab.FirstParagraph.AppendChild( run1 );

    Run run2 = new Run(d, "Jane Doe ");
    run2.Font.Name = "Arial";
    run2.Font.Italic = true;
    run2.Font.Size = 25;
    run2.Font.Color = Color.Violet;

    stepTab.FirstParagraph.AppendChild( run2 );

    stepTab.TextBox.LayoutFlow = LayoutFlow.TopToBottom;
    stepTab.FillColor = Color.FromArgb( 0, 0, 0);

If I comment out the area above, it seems to work. In fact, I can not get the text to display. Can you please review this section and give me ideas on how to correct. Is there a better technique?

What is a Run anyway?

Also, the black rectangle has a border. Any ideas why?

@adventurousbooks

Thanks for your inquiry.

You can change the border color of shape by using Shape.StrokeColor.

All text of the document is stored in runs of text. Run can only be a child of Paragraph. Run class represents a run of characters with the same font formatting.

Please ZIP and attach your problematic and expected output Word documents here for our reference. We will then provide you more information about your query.

Hello Tahir,

Thanks for the help, I solved the problem by designating the Shape as a TextBox instead of a Rectangle. I have another question that i hope you can help.

I want to create a TextBox with formatted text. I mean some paragraphs, some word phrases that are italized and/or bold and some font size changes.

How do I do that? How do I do that in my COM Wrapper. I think first to initiate a shape :

Shape stepTab = builder.InsertShape(ShapeType.TextBox,
RelativeHorizontalPosition.Page, leftInPoints,
RelativeVerticalPosition.Page, topInPoints,
widthInPoints, heightInPoints,
WrapType.None);

But then how do I stuff formatted text into the TextBox?

Thanks in advance,
Royn

@adventurousbooks

Thanks for your inquiry. All text of the document is stored in runs of text and Run node can only be a child of Paragraph node. You can use Run.Font property to format the text. Please read the following article.
Inserting a String of Text

In your case, you need to add paragraph node into text box (Shape node) and add run nodes into the paragraph.

Fantastic. I will get working on this and place with stuffing formatted text into a TextBox… I am looking for your guidance for some ideas on how to proceed.

  1. One option I am considering is to pass an HTML string to the text box. Will the HTML work for font changes and font size?

  2. Another option, is to send a coded string and parse he string and building the Run. This sounds like a lot of work.

  3. Thirdly is the issue of storage. Can Aspose Word read an XML file instead of passing a string; there upon I would execute #1 or #2 above.

There is another idea I have. Can I initiated a Word document without actually reading one first I mean, can I designate a file name, set the Word Document size, build the document, (This is a one page document) and save the document to file.

I really look forward to your insights.

Best,
Royn

@adventurousbooks

Thanks for your inquiry.

In your case, we suggest you please use this approach to achieve your requirement. Please read the following article.
Inserting HTML

Hey Tahir,

I will prototype the HTML option and thanks for the recommendation and link. A few more tidbits…

If a pass a photo (path) to the COM Wrapper. Is there a way to determine the image type, width, and height? Can you give me a code example?

Can I read and parse an XML with Aspose.Words? I am thinking about passing some information via an XML.

Your help is appreciated.

@adventurousbooks

Thanks for your inquiry.

Once you have inserted the image into document, you can work with image using Shape.ImageData property. This property provides access to the image of the shape. Returns null if the shape cannot have an image.

The ImageData.ImageSize property returns the information about image size and resolution. The ImageData.ImageType property returns the type of the image.

Aspose.Words does not provide API to read or parse XML. However, you can read the XML by using .NET API (DataSet.ReadXml method) and perform mail merge operation. We suggest you please read the following article.
About Mail Merge
How to Mail Merge from XML using DataSet

I have the COM Wrapper Method below. How do I determine and image size first (so I can calculate positioning) before I issue the builder.InsertImage. Please suggest alterations to code below.

============================================================

public void InsertPhoto( object docSource, object b, object imgPath )
{

        DocumentBuilder builder = (DocumentBuilder)b;
        Document d = (Document)docSource; 
        String photoPath = imgPath.ToString();

        double top = 0.00;
        double left = 0.00;     

        // *****************************************************
        // * I need to determine image size HERE so 
        // * I can adjust the top and left properties before
        // * the images is inserted below.
        // ****************************************************

        Shape coverPhoto = builder.InsertImage(photoPath,
                                RelativeHorizontalPosition.Page, left,
                                RelativeVerticalPosition.Page, top,
                                -1, -1, 
                               WrapType.None );

}

@adventurousbooks

You can not get the image’s size on document’s page without inserting it. Once you insert it into document, you can get its width and height using Shape.Width and Shape.Height properties. Please note that when you insert an image into document using DocumentBuilder.InsertImage method (String), it is scale to 100%.

Moreover, you can get the image’s size using .NET API as shown below.

System.Drawing.Image img = System.Drawing.Image.FromFile(photoPath);
Console.Write("Width: " + img.Width + ", Height: " + img.Height);

If you still face problem, please ZIP and attach your input and expected output documents along with image here for our reference. We will then provide you more information about your query.

Great, I will get the file dimensions as recommended. I am using builder.InsertImage. How would I insert the image so it is centered within a rectangle? furthermore, if the image is too big then it would change scale to fit the rectangle. Always keeping the original aspect ratio. Anything with Aspose.Words? Do I need to use C#. Please provide a CODE SNIPPET.

thanks very much,

@adventurousbooks

Please ZIP and attach your input and expected output Word documents along with image here for our reference. We will then provide you code example according to your requirement.

test2.pdf (37.7 KB)

Here is the desired output pdf file, With a description of my method below.


Method Name: InsertPhotoIntoFixedFrame()

Method Input Parameters: top, left, width, height, photoPath

Method Description: Draw a rectangular box from the input parameters (top, left, width, height) with a 2px border and transparent background. Place the input parameters photoPath inside the box that is centered horizontally and 20pts from top of the box border. If the photoPath is larger than the rectangular box then scale the photoPath it so it fits within the bounded rectangular box while maintaining the original aspect ratio of photoPath.


Thank again for all your help,

@adventurousbooks

In your case, we suggest you following solution.

  1. Create a table with one row and one cell.
  2. Move the cursor to the table’s cell.
  3. Insert the image in the table’s cell.
  4. Set the image’s width and height using Shape.Width and Shape.Height properties.
  5. Set image’s position using Shape.Left and Shape.Top properties.

Hope this helps you.