OpenOffice 遍历 TextTable 检测合并和拆分单元格(计算 colspan 和 rowspan)

Posted

技术标签:

【中文标题】OpenOffice 遍历 TextTable 检测合并和拆分单元格(计算 colspan 和 rowspan)【英文标题】:OpenOffice iterating through TextTable detect merged and split cells (calculate colspan and rowspan) 【发布时间】:2010-03-31 19:03:17 【问题描述】:

我正在使用 OpenOffice uno api 来遍历编写器文档中的所有文本。要迭代文本表,目前我正在使用 XTextTable 接口 getCellNames() 方法。我如何检测合并和拆分单元格。我想将表格导出为html,所以我应该计算colspan和rowspan。

我将不胜感激任何建议...我没有想法:(

【问题讨论】:

【参考方案1】:

我终于有了答案(实际上是 colspan 的一部分)。我知道这段代码很丑,但有一天我会重构它;)

public class Cell

    private List<string> _text = new List<string>();
    public List<string> Text 
     
        get  return _text; 
        set  _text = value; 
    
    public int ColSpan  get; set; 
    public int RowSpan  get; set; 

    public Cell(int colSpan, int rowSpan, List<string> text)
    
        ColSpan = colSpan;
        RowSpan = rowSpan;
        _text = text;
    

    public Cell(int colSpan, int rowSpan)
    
        ColSpan = colSpan;
        RowSpan = rowSpan;
    

这里是表格解析方法

    public static List<List<Cell>> ParseTable(XTextTable table)
    
        XTableRows rows = table.getRows() as XTableRows;
        int rowCount = rows.getCount();
        int sum = GetTableColumnRelativeSum(table);

        // Temprorary store for column count of each row
        int[] colCounts = new int[rowCount];

        List<List<int>> matrix = new List<List<int>>(rowCount);
        for (int i = 0; i < rowCount; i++)
            matrix.Add(new List<int>());

        // Get column count for each row
        int maxColCount = 0;
        for (int rowNo = 0; rowNo < rowCount; rowNo++)
        
            TableColumnSeparator[] sep = GetTableRowSeperators(rows, rowNo);
            colCounts[rowNo] = sep.Length + 1;

            if (maxColCount < colCounts[rowNo])
                maxColCount = colCounts[rowNo];

            for (int j = 0; j < sep.Length; j++)
                matrix[rowNo].Add(sep[j].Position);

            matrix[rowNo].Add(sum);
        

        int[] curIndex = new int[rowCount];
        List<List<Cell>> results = new List<List<Cell>>(rowCount);
        for (int i = 0; i < rowCount; i++)
            results.Add(new List<Cell>());

        int curMinSep = matrix[0][0];
        do
        
            curMinSep = matrix[0][curIndex[0]];
            for (int i = 0; i < rowCount; i++)
                if (curMinSep > matrix[i][curIndex[i]]) curMinSep = matrix[i][curIndex[i]];

            for (int rowNo = 0; rowNo < rowCount; rowNo++)
            
                int col = curIndex[rowNo];
                int lastIdx = results[rowNo].Count - 1;

                if (curMinSep == matrix[rowNo][col])
                
                    if (colCounts[rowNo] > col + 1) curIndex[rowNo] = col + 1;

                    if (results[rowNo].Count > 0 &&
                        results[rowNo][lastIdx].Text.Count < 1 &&
                        results[rowNo][lastIdx].ColSpan > 0)
                    
                        results[rowNo][lastIdx].ColSpan++;
                        results[rowNo][lastIdx].Text = GetCellText(table, rowNo, col);
                    
                    else
                    
                        results[rowNo].Add(new Cell(0, 0, GetCellText(table, rowNo, col)));
                    
                
                else
                
                    if (results[rowNo].Count > 0 &&
                        results[rowNo][lastIdx].Text.Count < 1)
                    
                        results[rowNo][lastIdx].ColSpan++;
                    
                    else
                    
                        results[rowNo].Add(new Cell(1, 0));
                    
                
            
         while (curMinSep < sum);

        return results;
    

    public static short GetTableColumnRelativeSum(XTextTable rows)
    
        XPropertySet xPropertySet = rows as XPropertySet;
        short sum = (short)xPropertySet.getPropertyValue("TableColumnRelativeSum").Value;
        return sum;
    

    public static TableColumnSeparator[] GetTableRowSeperators(XTableRows rows, int rowNo)
    
        XPropertySet rowProperties = rows.getByIndex(rowNo).Value as XPropertySet;
        TableColumnSeparator[] sep = null;
        sep = rowProperties.getPropertyValue("TableColumnSeparators").Value as TableColumnSeparator[];
        return sep;
    

【讨论】:

嗨,Darius,巧合的是,过去两天我也在尝试同样的事情,但没有成功。我尝试了不同的方法,使用 XTextTable.getCellNames 和 XTextTable.createCursorByCellName 并使用光标导航以找出单元格的邻域。但是由于表格内光标导航的非常奇怪(在我看来)行为,我没有成功。在您的代码中,您缺少 GetTableColumnRelativeSum 和 GetTableRowSeperators 方法,您也可以发布这些方法吗? 我不知道 TableColumnSeparators 是 TableRow 属性,在文档中我只发现该属性是 TextTable api.openoffice.org/docs/common/ref/com/sun/star/text/… @mvladic - 我不记得我是如何找到 TableColumnSeparators 的,我已经在互联网上挖掘了数周以获取有关 OOo API 的信息。 已经有一段时间了,但你有没有想过如何确定行跨度,即垂直跨越多行的单元格?我也在OO Forum 中发布了一个问题。

以上是关于OpenOffice 遍历 TextTable 检测合并和拆分单元格(计算 colspan 和 rowspan)的主要内容,如果未能解决你的问题,请参考以下文章

OpenOffice API - 表格的 OptimalWidth 选项(所有列)

如何使用 open office uno API 克隆 TextTable 并将 N 个克隆的 TextTable 粘贴到原始 TextTable 下方

如何使用 UNO 遍历 OpenOffice/LibreOffice 中的整个文档

Excel \ OpenOffice Calc Dir 函数不会遍历文件

使用 QtQuick.Controls 1.12 将 Qt TextTable 与 TextArea 一起使用时,文本会错位

使用 OpenOffice API 抓取整个文档树