由于word表格的特殊性,其本身中的数据本来就不够完善,不能够很好的知道其具体的合并、跨行的相关属性,表格的单位可能是PT或者是百分比,并且是共存的,为处理带来了一定的负担,本代码实现了一个将Word表格解析为XMLTable。
由于没找到上传附件的位置,仅提供部分代码,有需要的可email我(提供联系方式)或进群:490571636,我会提供全部代码。
/// <summary> /// 分析表格通过位置跨度 /// </summary> /// <param name="table">word表格对象</param> /// <returns>自定义的表格对象</returns> public static WordTable ParserTableByPositionSpan(Word.Table table) { List<double> positionList = new List<double>(); WordTable wordTable = new WordTable();
wordTable.RowCount = table.Rows.Count; wordTable.ColCount = table.Columns.Count; positionList.Add(0); double tableWidth = 0; //获取所有行中的单元格及位置列表 如果有的列没有获取,说明没有或被上边的单元格合并(只有上边被合并的列才会) for (var row = 1; row <= table.Rows.Count; row++) { WTRow currRow = wordTable.AddRow(); currRow.RowIndex = row; double leftPosition = 0; for (var col = 1; col <= table.Columns.Count; col++) { Word.Cell cell = null; try { //获取指定位置的单元格,如果没有会触发异常 cell = table.Cell(row, col); } catch (Exception e) { //System.Diagnostics.Trace. } //指定的位置有单元格则直接添加到当前行 if (cell != null) { //第一行的宽度肯定会有值不会了现9999999的情况 if (row == 1) { tableWidth += cell.Width; } WTCol wTCol = currRow.AddCol(); wTCol.Value = GetRangeParagraphs(cell.Range);
double width = cell.Width; //cell的宽度有三种形式 //按内容展示(磅值)Word.WdPreferredWidthType.wdPreferredWidthAuto 属性width有值 PreferredWidth为0 //固定宽度(磅值) Word.WdPreferredWidthType.wdPreferredWidthPoints 属性width有值 PreferredWidth有时为9999999 //匹配窗口(百分比)Word.WdPreferredWidthType.wdPreferredWidthPercent 属性width有时为9999999 PreferredWidth为百分比 switch (cell.PreferredWidthType) { case Word.WdPreferredWidthType.wdPreferredWidthAuto: width = cell.Width; break; case Word.WdPreferredWidthType.wdPreferredWidthPoints: ///9999999为百分比或磅值时 取PreferredWidth的宽度 if (width == 9999999) { width = cell.PreferredWidth; } break; case Word.WdPreferredWidthType.wdPreferredWidthPercent: ///9999999为百分比或磅值时 width和PreferredWidth所对应的宽度 if (width == 9999999) { width = GetPercentWidth(tableWidth, cell.PreferredWidth); } break; } wTCol.Width = width; wTCol.RealCol = col; wTCol.Left = leftPosition; leftPosition += width; AddNewPosition(positionList, leftPosition); continue; }
//WTCol prevRowWTCol1 = wordTable.GetPreviousRowRefCol(row, col); //WTCol prevRowWTCol2 = wordTable.GetPreviousRowRefColByLeft(row, leftPosition); WTCol prevRowWTCol1 = wordTable.GetPreviousRowRefColByLeft(row, leftPosition); //第一列 如果没有单元格说明被上边的行给合并了 if (prevRowWTCol1 != null) { //if (prevRowWTCol1.Left + prevRowWTCol1.Width > leftPosition) { prevRowWTCol1.RowSpan += 1; } leftPosition += prevRowWTCol1.Width; continue; } //if (prevRowWTCol2 != null) //{
//} //else } }
wordTable.ColCount = positionList.Count - 1;
//矫正列合并处理 由于列合并不会产生空的单元格,以列宽判断列合并情况(默认均为合并1列) foreach (var row in wordTable.Rows) { //int realColCount = 1; foreach (var col in row.Cols) { int colSpan = GetPositionSpan(positionList, col.Left, col.Left + col.Width);
col.ColSpan = colSpan; col.RealCol = GetRealColByPositionList(positionList, col.Left); //realColCount; //realColCount += colSpan; //realColCount } }
return wordTable; }