We're sorry Aspose doesn't work properply without JavaScript enabled.

Free Support Forum - aspose.com

Bookmark and Table

Hello,

I am trying to convert DCOM Word to Apose. Most of it is straight forward.However I can't solve the following problem:

I have in a document a table. The first cell contains a BookMark. In de MSWord enviroment I was ableto set tekst in the cell, move to the cell right, set text and add a new row, set text, move cell to right and set text aso.

There are over 100 templates, so we would like to keep the bookmarks in the table.

Can someone help me how to solve this?

re

Hi<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thanks for your inquiry. You can use DocumentBuilder to achieve what you need. I create an example for you. See the following code and the attached documents.

//Create some datasource

DataTable tab = new DataTable();

tab.Columns.Add("col1");

tab.Columns.Add("col2");

tab.Columns.Add("col3");

tab.Columns.Add("col4");

tab.Columns.Add("col5");

//Add some data

for (int i = 0; i < 20; i++)

{

tab.Rows.Add(new object[] { "val0_" + i.ToString(), "val1_" + i.ToString(), "val2_" + i.ToString(), "val3_" + i.ToString(), "val4_" + i.ToString() });

}

//Open document

Document doc = new Document("in.doc");

//Creade DocumentBuilder

DocumentBuilder builder = new DocumentBuilder(doc);

//Move DocumentBuildr cursor to bookmark

builder.MoveToBookmark("myBookmark");

//Get cell where bookmark is placed

Cell refCell = builder.CurrentNode.GetAncestor(NodeType.Cell) as Cell;

if (refCell != null)

{

//Create copy of Row where bookmark is placed

Row srcRow = (Row)refCell.ParentRow.Clone(true);

//Loop through all rows in datasource table

foreach (DataRow data in tab.Rows)

{

//Loop through all columns in the datarow

foreach (DataColumn col in tab.Columns)

{

//Insert data into the current cell

builder.Write(data[col].ToString());

//Move to next cell

if (refCell.NextSibling != null)

{

refCell = (refCell.NextSibling as Cell);

builder.MoveTo(refCell.LastParagraph);

}

else

{

break;

}

}

if (!data.Equals(tab.Rows[tab.Rows.Count - 1]))

{

//Add new row

Row newRow = (Row)srcRow.Clone(true);

refCell.ParentRow.ParentTable.Rows.Add(newRow);

//Move cursor to the first cell of the newly created row

refCell = newRow.FirstCell;

builder.MoveTo(newRow.FirstCell.LastParagraph);

}

}

}

//Save document

doc.Save("out.doc");

I hope this could help you.

Also I think that the better way to achieve this is using mail merge feature, but then you should change your templates. See the following links for more information.

http://www.aspose.com/documentation/file-format-components/aspose.words-for-.net-and-java/mail-merge-with-regions-explained.html

Best regards.

Hi,

thanks for the help. I converted the project in 6 hours from WORD DCOM to Aspose. And the performance is great.

I can't use the mail merge, but what I have is now ok.

However if have 1 problem with the following code:

foreach(Bookmark elem in doc.Document.Range.Bookmarks)
{
n=elem.Name;
try{
t=elem.Text;
}
catch(Exception x1)
{
t=x1.Message + "{"+n+"}";
}

I get an error on the elem.Text at some bookmarks. The error is:

Start and end node should have the same grand parent.

Any clue what this is?

re bert

Hello!<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thank you for asking this.

Your case corresponds to a known issue:

#502 – Allow to get and set bookmark text when start and end have different grand parents

As a workaround you can traverse nodes programmatically from bookmark start to bookmark end. In general getting text in not so complex as setting it to a new value. Let us know if you have difficulties with this.

Regards,

Hello

I still can get it to work. The rest of our application is working.

this is the snippit of my code:

public void ActionList(DocumentBuilder doc, string bookmark)

{

bool first=true;

SetBookMark(doc, bookmark, ""); //The bookmark has a defualttext in it whcih should not be displayed

doc.MoveToBookmark(bookmark); //This should be in a table!!!

Cell refCell = (Cell)doc.CurrentNode.GetAncestor(NodeType.Cell);

Row copyRow = (Row)refCell.ParentRow.Clone(true);

foreach (string Text in AllText)

{

if (first) //Eerste keer niet naar nieuwe cell springen, want daar sta je al

first=false;

else

{

Row newRow = (Row)copyRow.Clone(true);

refCell.ParentRow.ParentTable.Rows.Add(newRow);

//Move cursor to the first cell of the newly created row

refCell = newRow.FirstCell;

doc.MoveTo(refCell);

}

doc.Write(Text);

}

However, it looks likes it copies(dupplicates) also the BookMark defined in the 1st row. Then I get this error.

What I need is a copy of the 1st row, without the bookmark. De row should be empty and I need to add text in ech cell.

Hi<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thanks for your inquiry. I think that error occurs in the following line:

doc.MoveTo(refCell);

This occurs because parameter of MoveTo method should be a Paragraph or a direct child of a Paragraph (e. g. Run).

In my example you can see the following

builder.MoveTo(refCell.LastParagraph);

Hope this helps.

Best regards.

Hi, sorry for giving you the wrong code. In my code I have the refCell.LastParagraph, however the error is still there:

Start and end node should have the same grand parent.

And the only reason I can think of is that the bookmark is also copied to the next line(s). Is there anyway I can just clear all the cells in the newRow. I then expect that the bookmark is also gone.

Thanks for you fast response and help.

Hi<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thank you for additional information. Could you also attach your document for testing? I will try to reproduce this issue and provide you more information.

Best regards.

I have attached the document (sorry for the Dutch Part).

Please look at the 2 tables with the bookmarks start with bl__

Please rename the attachment from .txt to .dot

Hi<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thanks for your inquiry. I can’t reproduce this issue on my side. You can try to remove all content from the cell before inserting text. Please see the following code:

string[] AllText = { "test1", "test2", "test3" };

bool first = true;

//Open document

Document doc = new Document(@"Test251\Memo.dot");

//Creade DocumentBuilder

DocumentBuilder builder = new DocumentBuilder(doc);

//Move DocumentBuildr cursor to bookmark

builder.MoveToBookmark("bl__KopieLijst"); //bl__ActieLijst bl__KopieLijst

//Get cell where bookmark is placed

Cell refCell = builder.CurrentNode.GetAncestor(NodeType.Cell) as Cell;

if (refCell != null)

{

//Create copy of Row where bookmark is placed

Row copyRow = (Row)refCell.ParentRow.Clone(true);

//Loop through all rows in datasource

foreach (string Text in AllText)

{

if (first)

first = false;

else

{

Row newRow = (Row)copyRow.Clone(true);

refCell.ParentRow.ParentTable.Rows.Add(newRow);

//Move cursor to the first cell of the newly created row

refCell = newRow.FirstCell;

builder.MoveTo(refCell.LastParagraph);

}

//Remove all content from cell

while (refCell.Paragraphs.Count > 1)

refCell.FirstParagraph.Remove();

refCell.LastParagraph.RemoveAllChildren();

builder.MoveTo(refCell.LastParagraph);

//Insert text into the cell

builder.Write(Text);

}

}

//Save document

doc.Save(@"Test251\out.doc");

Also please tell me which version of Aspose.Words are you using. I use the latest (5.2.0) version for testing.

Best regards.

Hi, that is working. Thanks.

Can I ask another question? Is it possible to print the document on a printer connected to the server. it is enough to give me a link to an example.

again thanks and a great product.

Hi<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thanks for your inquiry. You can use Aspose.Words.Viewer namespace for document printing. Please see the following link for more information.

http://www.aspose.com/documentation/file-format-components/aspose.words-for-.net-and-java/aspose.words.viewer.html]

Here is code example

Document doc = new Document("in.doc");

DocumentRenderer renderer = new DocumentRenderer(doc);

renderer.Print();

But note that Aspose.Words.Viewer namespace is currently in beta and limited technical support is provided for it.

Best regards.

Hi<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

We are happy to tell you that the new Rendering Engine has replaced the “old Viewer Beta”. The Rendering Engine can print, save as images or draw onto .NET Graphics object any document page.

Please see Aspose.Words documentation to learn more about new features.

SaveToImage method renders document pages into images:

http://www.aspose.com/documentation/file-format-components/aspose.words-for-.net-and-java/aspose.words.document.savetoimage_overloads.html

In additional, new Rendering engine allows you to convert Word document to PDF directly (without using Aspose.Pdf).

SaveToPdf method converts the whole document or selected pages to PDF.

http://www.aspose.com/documentation/file-format-components/aspose.words-for-.net-and-java/aspose.words.document.savetopdf_overloads.html

The latest version of Aspose.Words is available for download from here:

http://www.aspose.com/community/files/51/file-format-components/aspose.words/entry158153.aspx

Best regards,

The issues you have found earlier (filed as 502) have been fixed in this update.

I think this would make a great piece in the ‘How to’ in the documentation.

The solution of how to add to an existing table is not obvious. I would not have thought of cloning rows to add to the table.
The current documentation only shows creating a new table, which has styling issues since we have no way to set the table style.

Thank you for this gem.

Hi there,

Thank you for your suggestion.

Yes, I think an example of how to clone a Row or Cell in order to easily retain formatting is a good idea. I will add it to the documentation.

Thanks,