I have a table with 2 columns of 3 rows in a DocumentFormat OpenXML Wordprocessing table. I'm trying to merge the cells in the first column vertically. After running the code and opening the resulting file in Word the merge looks complete and good (column 1 has only 1 cell). But if I then go, in Word, and manually resize the column the merge vanishes and I'm back to 3 individual cells in column 1.
The code is practically straight from the OpenXML SDK examples. Only thing I'm doing differently is downloading the file, since the code is running in a vanilla ASP.Net Web Application.
I've tried applying the merge to each individual cell when it is created, and I've tried applying the merge at the end (after all the cells are created), but same problem no matter what.
Oddly, the problem does not occur with horizontal merge; the merge persists in Word even if you manually resize the columns in Word.
Here's a screenshot of the table opened in Word after downloading the file:
And here it is after I manually resize the column or resize the table:
I've seen all the MS docs (documentation examples and other SO posts about vertical merging cell but nothing mentions this problem.
I need the vertical merge to persist in Word. Any help much appreciated. Thanks
using System;
using System.Diagnostics;
using System.IO;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using Table = DocumentFormat.OpenXml.Wordprocessing.Table;
using TableCell = DocumentFormat.OpenXml.Wordprocessing.TableCell;
using TableRow = DocumentFormat.OpenXml.Wordprocessing.TableRow;
namespace WebApplication9.betseyPages
{
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
GenerateTable();
}
private void GenerateTable()
{
string strFileName = "";
bool endRequest = false;
Table table;
TableProperties props;
Body body;
Paragraph para;
Run run;
TableRow trColHdr;
TableRow trData;
TableCell tc;
TableRow trMerge;
strFileName = string.Format("TestTable_{0}.docx", DateTime.Now.ToString("yyyyMMddHHmm"));
try
{
using (MemoryStream stream = new MemoryStream())
{
using (var wordDocument = WordprocessingDocument.Create(stream, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
body = mainPart.Document.AppendChild(new Body());
para = body.AppendChild(new Paragraph());
run = para.AppendChild(new Run());
run.AppendChild(new Text("Create text in body - CreateWordprocessingDocument"));
table = body.AppendChild(new Table());
props = table.AppendChild(new TableProperties
{
TableBorders = new TableBorders
{
TopBorder = new TopBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
BottomBorder = new BottomBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
LeftBorder = new LeftBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
RightBorder = new RightBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
}
},
TableLayout = new TableLayout { Type = TableLayoutValues.Autofit },
TableWidth = new TableWidth { Type = TableWidthUnitValues.Auto }
});
// Column header -------------------------------------------------------------------------------
trColHdr = new TableRow();
trColHdr.AppendChild(GetColHdrTc("col A", true, MergedCellValues.Restart));
trColHdr.AppendChild(GetColHdrTc("col B", true, MergedCellValues.Restart));
table.AppendChild(trColHdr);
// Data row 1 ------------------------------------------------------------------------------------------
trData = new TableRow();
trData.AppendChild(GetDataTc("Biff", true, MergedCellValues.Restart));
trData.AppendChild(GetDataTc("Scibb", true, MergedCellValues.Restart));
table.AppendChild(trData);
// Data row 2 ------------------------------------------------------------------------------------------
trData = new TableRow();
trData.AppendChild(GetDataTc("Biff", true, MergedCellValues.Continue ));
trData.AppendChild(GetDataTc("Scabb", true, MergedCellValues.Restart));
table.AppendChild(trData);
// Data row 2 ------------------------------------------------------------------------------------------
trData = new TableRow();
trData.AppendChild(GetDataTc("Biff", true, MergedCellValues.Continue ));
trData.AppendChild(GetDataTc("Scobb", true, MergedCellValues.Restart));
table.AppendChild(trData);
// -------------------------------------------------------------------------------------------
para = body.AppendChild(new Paragraph());
run = para.AppendChild(new Run());
run.AppendChild(new Text("Line Break Here"));
}
stream.Seek(0, SeekOrigin.Begin);
stream.Capacity = (int)stream.Length;
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
Response.AddHeader("content-disposition", "attachment;filename=\"" + strFileName + "\"");
// 'close document and output
stream.WriteTo(Response.OutputStream);
Response.Flush();
endRequest = true;
}
}
catch (Exception ex)
{
Debug.Print(ex.Message);
Response.StatusCode = 500;
Response.ContentType = "text/plain";
Response.Write(ex.Message);
Response.End();
}
if(endRequest)
Response.End();
}
private TableCell GetColHdrTc(string colTxt, bool mergeEm, MergedCellValues mcv)
{
TableCell tc = new TableCell();
tc.AppendChild(new Paragraph(new Run(new Text(colTxt), new RunProperties(new Bold() { Val = OnOffValue.FromBoolean(true) }))));
if (mergeEm)
tc.Append(new TableCellProperties { VerticalMerge = new VerticalMerge { Val = mcv } });
return tc;
}
private TableCell GetDataTc(string colTxt, bool mergeEm, MergedCellValues mcv) {
TableCell tc = new TableCell();
tc.AppendChild(new Paragraph(new Run(new Text(colTxt))));
if(mergeEm)
tc.Append(new TableCellProperties { VerticalMerge = new VerticalMerge { Val = mcv } });
return tc;
}
}
}
I have a table with 2 columns of 3 rows in a DocumentFormat OpenXML Wordprocessing table. I'm trying to merge the cells in the first column vertically. After running the code and opening the resulting file in Word the merge looks complete and good (column 1 has only 1 cell). But if I then go, in Word, and manually resize the column the merge vanishes and I'm back to 3 individual cells in column 1.
The code is practically straight from the OpenXML SDK examples. Only thing I'm doing differently is downloading the file, since the code is running in a vanilla ASP.Net Web Application.
I've tried applying the merge to each individual cell when it is created, and I've tried applying the merge at the end (after all the cells are created), but same problem no matter what.
Oddly, the problem does not occur with horizontal merge; the merge persists in Word even if you manually resize the columns in Word.
Here's a screenshot of the table opened in Word after downloading the file:
And here it is after I manually resize the column or resize the table:
I've seen all the MS docs (documentation examples and other SO posts about vertical merging cell but nothing mentions this problem.
I need the vertical merge to persist in Word. Any help much appreciated. Thanks
using System;
using System.Diagnostics;
using System.IO;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using Table = DocumentFormat.OpenXml.Wordprocessing.Table;
using TableCell = DocumentFormat.OpenXml.Wordprocessing.TableCell;
using TableRow = DocumentFormat.OpenXml.Wordprocessing.TableRow;
namespace WebApplication9.betseyPages
{
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
GenerateTable();
}
private void GenerateTable()
{
string strFileName = "";
bool endRequest = false;
Table table;
TableProperties props;
Body body;
Paragraph para;
Run run;
TableRow trColHdr;
TableRow trData;
TableCell tc;
TableRow trMerge;
strFileName = string.Format("TestTable_{0}.docx", DateTime.Now.ToString("yyyyMMddHHmm"));
try
{
using (MemoryStream stream = new MemoryStream())
{
using (var wordDocument = WordprocessingDocument.Create(stream, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
body = mainPart.Document.AppendChild(new Body());
para = body.AppendChild(new Paragraph());
run = para.AppendChild(new Run());
run.AppendChild(new Text("Create text in body - CreateWordprocessingDocument"));
table = body.AppendChild(new Table());
props = table.AppendChild(new TableProperties
{
TableBorders = new TableBorders
{
TopBorder = new TopBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
BottomBorder = new BottomBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
LeftBorder = new LeftBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
},
RightBorder = new RightBorder
{
Val = new EnumValue<BorderValues>(BorderValues.Single),
Size = 12
}
},
TableLayout = new TableLayout { Type = TableLayoutValues.Autofit },
TableWidth = new TableWidth { Type = TableWidthUnitValues.Auto }
});
// Column header -------------------------------------------------------------------------------
trColHdr = new TableRow();
trColHdr.AppendChild(GetColHdrTc("col A", true, MergedCellValues.Restart));
trColHdr.AppendChild(GetColHdrTc("col B", true, MergedCellValues.Restart));
table.AppendChild(trColHdr);
// Data row 1 ------------------------------------------------------------------------------------------
trData = new TableRow();
trData.AppendChild(GetDataTc("Biff", true, MergedCellValues.Restart));
trData.AppendChild(GetDataTc("Scibb", true, MergedCellValues.Restart));
table.AppendChild(trData);
// Data row 2 ------------------------------------------------------------------------------------------
trData = new TableRow();
trData.AppendChild(GetDataTc("Biff", true, MergedCellValues.Continue ));
trData.AppendChild(GetDataTc("Scabb", true, MergedCellValues.Restart));
table.AppendChild(trData);
// Data row 2 ------------------------------------------------------------------------------------------
trData = new TableRow();
trData.AppendChild(GetDataTc("Biff", true, MergedCellValues.Continue ));
trData.AppendChild(GetDataTc("Scobb", true, MergedCellValues.Restart));
table.AppendChild(trData);
// -------------------------------------------------------------------------------------------
para = body.AppendChild(new Paragraph());
run = para.AppendChild(new Run());
run.AppendChild(new Text("Line Break Here"));
}
stream.Seek(0, SeekOrigin.Begin);
stream.Capacity = (int)stream.Length;
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
Response.AddHeader("content-disposition", "attachment;filename=\"" + strFileName + "\"");
// 'close document and output
stream.WriteTo(Response.OutputStream);
Response.Flush();
endRequest = true;
}
}
catch (Exception ex)
{
Debug.Print(ex.Message);
Response.StatusCode = 500;
Response.ContentType = "text/plain";
Response.Write(ex.Message);
Response.End();
}
if(endRequest)
Response.End();
}
private TableCell GetColHdrTc(string colTxt, bool mergeEm, MergedCellValues mcv)
{
TableCell tc = new TableCell();
tc.AppendChild(new Paragraph(new Run(new Text(colTxt), new RunProperties(new Bold() { Val = OnOffValue.FromBoolean(true) }))));
if (mergeEm)
tc.Append(new TableCellProperties { VerticalMerge = new VerticalMerge { Val = mcv } });
return tc;
}
private TableCell GetDataTc(string colTxt, bool mergeEm, MergedCellValues mcv) {
TableCell tc = new TableCell();
tc.AppendChild(new Paragraph(new Run(new Text(colTxt))));
if(mergeEm)
tc.Append(new TableCellProperties { VerticalMerge = new VerticalMerge { Val = mcv } });
return tc;
}
}
}
Share
Improve this question
edited Mar 30 at 6:55
unqualified
asked Mar 30 at 6:50
unqualifiedunqualified
1312 silver badges6 bronze badges
1 Answer
Reset to default 0Solved it. Only the first cell can have text. So, remove all text (and runs) from subsequent cells in the merge.
Something like:
tc = table.Elements<TableCell>();
foreach (Paragraph pg in tc.Elements<Paragraph>())
pg.RemoveAllChildren();