1

I am using OpenOffice uno api to iterate through all text in writer document. To iterate over text tables currently I am using XTextTable interface getCellNames() method. How I could detect merged and split cells. I want to export table to html, so I should calculate colspan and rowspan.

I would appreciate any suggestions... I am out of ideas :(

Darius Kucinskas
  • 10,193
  • 12
  • 57
  • 79

1 Answers1

2

Finally I have the answer (actually colspan part of it). This code is ugly I know, but one day I'll refactor it ;)

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;
    }
}

and here it is table parse method

    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 Kucinskas
  • 10,193
  • 12
  • 57
  • 79
  • Hi Darius, coincidently I'm trying the same thing for the last two days without success. I've tried with different approach by using XTextTable.getCellNames and XTextTable.createCursorByCellName and navigating with cursor to find out neighborhoods of the cell. But because of very strange (in my opinion) behavior of cursor navigation inside table I didn't succeeded. In your code you are missing GetTableColumnRelativeSum and GetTableRowSeperators method, could you post those methods too. – mvladic Mar 04 '11 at 15:00
  • I didn't know that TableColumnSeparators is TableRow property, in documentation I only find that property to be part of TextTable http://api.openoffice.org/docs/common/ref/com/sun/star/text/TextTable.html#TableColumnSeparators – mvladic Mar 04 '11 at 15:45
  • @mvladic - I don't remember how I found about TableColumnSeparators I was digging internet for weeks for information about OOo API's. – Darius Kucinskas Mar 04 '11 at 15:49
  • It’s been a while, but did you ever figure out how to determine rowspan, i.e. cells spanning multiple rows vertically? I posted a question in an [OO Forum](https://forum.openoffice.org/en/forum/viewtopic.php?f=45&t=103920), too. – Jens Dec 17 '20 at 07:50