有没有办法在 C# 中使用 OpenXml 库来固定列的宽度?

Is there a way to fix the width of a column using OpenXml Library in C#?

我有一个包含 2 列的 Word table。我试图让 Word 在 column2 包含长文本换行时不挤压 column1。

这是预期的布局:

 column1   Column2                
 -------   -------                
 1.        Long text that wraps   
           a couple of times.     
           Another paragraph of   
           long text that wraps.  

 2.        More long text that    
           wraps again.           
           Also another paragraph 
           of long wrapping text. 

注意第 2 列的每个单元格中有 2 个段落。不确定这是否重要,但这就是必须包含的内容。

当 table 行数达到两位数并且在我以编程方式将完成的文档发送到客户端站点上的浏览器后(他们将其视为下载并在 Word 中打开),这就是发生的情况:

 column1   Column2                
 -------   -------                
 .         .
 .         .

 9.        Long text that wraps   
           a couple of times.     
           Another paragraph of   
           long text that wraps.  

 1         More long text that    
 0.         wraps again.           
           Also another paragraph 
           of long wrapping text. 

 1         More long text that    
 1.        wraps again.           
           Also another paragraph 
           of long wrapping text. 

注意“10”是怎么来的。和“11”。在 column1 中换行(因为 Word 决定压缩该列的宽度,...我认为)

我尝试增加 GridColumn 的宽度(甚至增加到一个很大的值)但无济于事。 Word 似乎总是将列宽调整为它认为最合适的大小……我认为。我在其他论坛(不是 Microsoft 网站)上读到,所有宽度设置仅被视为 "preferred"。不确定这是不是真的,但在这种情况下似乎足够真实!!

我试过设置

new TableCellProperties()
{
  Width = "4000",
  Type = TableWidthUnitValues.Pct
}

还有

{
  Width = "3170",
  Type = TableWidthUnitValues.Dxa
}

我也试过 table 布局设置为固定:

类型 = TableLayoutValues.Fixed

同时在 table 属性中将 table 单元格边距和 TableCellSpacing 设置为 0;但没有任何帮助。

是否有任何 OpenXml API 告诉 Word 不要弄乱列宽?

对于那些感兴趣的人,我终于解决了这个问题。

解决方案是完全放弃 table 对象。相反,我只依赖段落。

网上有几个讨论明确提到Word中table对象的column-widths不能通过OpenXml精确控制。我不确定这是否属实,但正如我在上面的问题中提到的,我尝试过的任何事情都没有帮助。在使用 OpenXml SDK 工具从 Word 中提取代码之前,甚至没有修复 Word 本身的宽度。也没有人提供具体的替代方案。

但是,使用带有缩进和对齐对象的段落并嵌入制表符,将段落的内容分成 2 "columns,",其中右列准确地换行缩进。给我上面问题中 table 中的确切期望结果。也没有挤压 column1。

我遇到了同样的问题,但我可以使用 TableLayout 属性。

// First, we create the table, its properties and we append it.
Table table = new Table();
TableProperties props = new TableProperties();
table.AppendChild<TableProperties>(props);

// Now we create a new layout and make it "fixed".
TableLayout tl = new TableLayout(){ Type = TableLayoutValues.Fixed };
props.TableLayout = tl;

// Then we just create a new row and a few cells and we give them a width
var tr = new TableRow();
var tc1 = new TableCell();
var tc2 = new TableCell();
tc1.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = "2000" }));
tc2.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = "2000" }));
table.Append(tr);

现在,当我们向 table 添加文本时,不再重新缩放。

我使用此代码来调整特定列的宽度,而所有其他列都会根据其内容自动调整。

Table tbl = new Table();

TableProperties tableProp = new TableProperties();
TableStyle tableStyle = new TableStyle() { Val = "TableGrid" };

// Make the table width 100% of the page width.
TableWidth tableWidth = new TableWidth() { Width = "5000", Type = TableWidthUnitValues.Pct };

tableProp.Append(tableStyle, tableWidth);

tbl.AppendChild(tableProp);

//Add n columns to table
TableGrid tg = new TableGrid(new GridColumn(), new GridColumn());

tbl.AppendChild(tg);

TableRow tr1 = new TableRow();

//I Manually adjust width of the first column
TableCell tc1 = new TableCell(GenerateTableCellPropsWithWidth("270"), new Paragraph(new Run(new Text("№"))));

//All other column are adjusted based on their content
TableCell tc2 = new TableCell(GenerateTableCellPropsWithWidth(), new Paragraph(new Run(new Text("Title"))));

tr1.Append(tc1, tc2);
tbl.AppendChild(tr1);

//This method is only used for headers, while regular rows cells contain no TableCellProperties
private TableCellProperties GenerateTableCellPropsWithWidth(string width = null)
{
    TableCellProperties tcp = new TableCellProperties();
    tcp.AppendChild(width.IsNullOrEmpty()
        ? new TableCellWidth {Type = TableWidthUnitValues.Auto}
        : new TableCellWidth {Type = TableWidthUnitValues.Pct, Width = width});
    return tcp;
}