问题
Doing research for ASPOSE.Words. Everything works fine just last thing remains. Question is how to render table inside table? In the Nested table documentation sample data is tightly coupled with presentation layer. I need separation of data and presentation layer. So little test here:
[Test]
public void CreateDocumentRecurentalTableInTableTest()
{
// Structural items are in [], values/data in {}
//GIVEN (presentation layer)
const string FileName = "_6CreateDocumentRecurentalTableInTableTest.txt";
var doc = new Document();
var builder = new DocumentBuilder(doc);
builder.Writeln("TEST -- START");
builder.InsertField(@"MERGEFIELD TableStart:[MyTable] MERGEFORMAT");
builder.InsertField(@"MERGEFIELD [MyTableCol1] \* MERGEFORMAT");
builder.InsertField(@"MERGEFIELD [MyTableCol2] \* MERGEFORMAT");
builder.InsertField(@"MERGEFIELD TableStart:[SubTable] MERGEFORMAT");
builder.InsertField(@"MERGEFIELD [SubTable.Col1] \* MERGEFORMAT");
builder.InsertField(@"MERGEFIELD [SubTable.Col2] \* MERGEFORMAT");
builder.InsertField(@"MERGEFIELD TableEnd:[SubTable] MERGEFORMAT");
builder.InsertField(@"MERGEFIELD TableEnd:[MyTable] MERGEFORMAT");
builder.Writeln("\nTEST -- END");
//WHEN (Data layer)
using (var dt2 = new DataTable("[SubTable]"))
{
dt2.Columns.Add("[SubTable.Col1]");
dt2.Columns.Add("[SubTable.Col2]");
dt2.Rows.Add(" {SubTable.Row1.Cont1} ", " {SubTable.Row1.Cont2} ");
dt2.Rows.Add(" {SubTable.Row2.Cont1} ", " {SubTable.Row2.Cont2} ");
dt2.Rows.Add(" {SubTable.Row3.Cont1} ", " {SubTable.Row3.Cont2} ");
using (var dt = new DataTable("[MyTable]"))
{
dt.Columns.Add("[MyTableCol1]");
dt.Columns.Add("[MyTableCol2]");
dt.Rows.Add(" {MyTable.firstRow} ", dt2);
doc.MailMerge.ExecuteWithRegions(dt);
doc.Save(FileName, SaveFormat.Text);
}
}
//THEN
//Assert...
}
Getting result:
TEST -- START
{MyTable.firstRow} [SubTable]«TableStart:[SubTable]»«[SubTable.Col1]»«[SubTable.Col2]»«TableEnd:[SubTable]»
TEST -- END
What I am trying to achieve:
TEST -- START
{MyTable.firstRow} {SubTable.Row1.Cont1} {SubTable.Row1.Cont2}
{SubTable.Row2.Cont1} {SubTable.Row2.Cont2}
{SubTable.Row3.Cont1} {SubTable.Row3.Cont2}
{MyTable.nextRow}
TEST -- END
If both tables are stored in DataSet.Tables then it renders mutiple times per each table:
TEST -- START
{MyTable.firstRow} {SubTable.Row1.Cont1} {SubTable.Row1.Cont2}
{MyTable.firstRow} {SubTable.Row2.Cont1} {SubTable.Row2.Cont2}
{MyTable.firstRow} {SubTable.Row3.Cont1} {SubTable.Row3.Cont2}
{MyTable.nextRow} {SubTable.Row1.Cont1} {SubTable.Row1.Cont2}
{MyTable.nextRow} {SubTable.Row2.Cont1} {SubTable.Row2.Cont2}
{MyTable.nextRow} {SubTable.Row3.Cont1} {SubTable.Row3.Cont2}
TEST -- END
回答1:
Perform required re-factoring to both the presentation layer and data layer codes as follows:
public void CreateDocumentRecurentalTableInTableTest()
{
// Structural items are in [], values/data in {}
//GIVEN (presentation layer)
//const string FileName = "_6CreateDocumentRecurentalTableInTableTest.txt";
var doc = new Document();
var builder = new DocumentBuilder(doc);
builder.Writeln("TEST -- START");
builder.InsertField(@"MERGEFIELD TableStart:[MyTable] MERGEFORMAT");
builder.InsertField(@"MERGEFIELD [MyTableCol1] \* MERGEFORMAT");
builder.InsertField(@"MERGEFIELD [MyTableCol2] \* MERGEFORMAT");
builder.Writeln();
builder.InsertField(@"MERGEFIELD TableStart:[SubTable] MERGEFORMAT");
builder.InsertField(@"MERGEFIELD [SubTable.Col1] \* MERGEFORMAT");
builder.InsertField(@"MERGEFIELD [SubTable.Col2] \* MERGEFORMAT");
builder.InsertField(@"MERGEFIELD TableEnd:[SubTable] MERGEFORMAT");
builder.Writeln();
builder.InsertField(@"MERGEFIELD TableEnd:[MyTable] MERGEFORMAT");
builder.Writeln("\nTEST -- END");
//WHEN (Data layer)
DataSet ds = new DataSet();
var dt = new DataTable("[MyTable]");
dt.Columns.Add("[MyTableCol1]");
dt.Columns.Add("[MyTableCol2]");
dt.Columns.Add("[Id]");
dt.Rows.Add(" {MyTable.firstRow} ", "", 0);
dt.Rows.Add(" {MyTable.nextRow} ", "", 1);
var dt2 = new DataTable("[SubTable]");
dt2.Columns.Add("[SubTable.Col1]");
dt2.Columns.Add("[SubTable.Col2]");
dt2.Columns.Add("[Id]");
dt2.Rows.Add(" {SubTable.Row1.Cont1} ", " {SubTable.Row1.Cont2} ", 0);
dt2.Rows.Add(" {SubTable.Row2.Cont1} ", " {SubTable.Row2.Cont2} ", 0);
dt2.Rows.Add(" {SubTable.Row3.Cont1} ", " {SubTable.Row3.Cont2} ", 0);
ds.Tables.Add(dt);
ds.Tables.Add(dt2);
ds.Relations.Add("MyRelation", dt.Columns[2], dt2.Columns[2], true);
doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveUnusedRegions | MailMergeCleanupOptions.RemoveEmptyParagraphs;
doc.MailMerge.ExecuteWithRegions(ds);
doc.Save(@"C:\Temp\\out.docx");
//THEN
//Assert...
}
This gives the exact same output as you desired, that is like:
TEST -- START
{MyTable.firstRow}
{SubTable.Row1.Cont1} {SubTable.Row1.Cont2}
{SubTable.Row2.Cont1} {SubTable.Row2.Cont2}
{SubTable.Row3.Cont1} {SubTable.Row3.Cont2}
{MyTable.nextRow}
TEST -- END
My name is Iqbal and I am developer evangelist at Aspose.
回答2:
In short: data tables must be linked (like RDBMS).
In brief: Read more here.
来源:https://stackoverflow.com/questions/15222963/aspose-nested-tables