紧接上回,重新定义了两个类,一个封装单元格数据及属性,一个封装由单元格组装成的table,接下来要做的就是要分析清楚哪些是变化的而哪些是不变的。对于不变的东西就应该提取出公共方法,而变化的东西就要分类对待。其中核心定义及方法如下:
/// <summary>
/// 定义单元格内容及属性
/// </summary>
/// <param name="context">内容</param>
/// <param name="row">行号</param>
/// <param name="column">列号</param>
/// <param name="rowspan">单元格所占的行数</param>
/// <param name="colspan">单元格所占的列数</param>
/// <param name="rowspanStartIndex">单元格开始合并的行号</param>
/// <param name="colspanStartIndex">单元格开始合并的列号</param>
public TableForExcelCell(string context, int row, int column, int rowspan, int colspan, int rowspanStartIndex, int colspanStartIndex)
{
RowIndex = row;
ColumnIndex = column;
RowSpan = rowspan;
ColumnSpan = colspan;
RowSpanStartIndex = rowspanStartIndex;
ColumnSpanStartIndex = colspanStartIndex;
Context = context;
}
此为单元格类的属性及初始化方法。
/// <summary>
/// 按合并条件填充cell所占区域的内容
/// </summary>
/// <param name="context">内容</param>
/// <param name="row">行号</param>
/// <param name="column">列号</param>
/// <param name="rowspan">所占行数</param>
/// <param name="colspan">所占列数</param>
public void SetCellContext(string context, int row, int column, int rowspan, int colspan)
{
//先判断要填充的单元格是否存在,不存在则新建
//行不存在则新建行
if ((row + rowspan) > (RowCount - 1))
{
AddRow(row + rowspan);
}
//列不存在则新建列
if ((column + colspan) > (ColumnCount - 1))
{
AddColumn(column + colspan);
}
//填充内容——若插入的单元格在已经经过合并的单元格范围内,则将先前合并的单元格拆开后再填充
for (int i = row; i < (row + rowspan); i++)
{
for (int j = column; j < (column + colspan); j++)
{
if (m_Table[i][j] == null) //未填充过,则进行首次填充
{
m_Table[i][j] = new TableForExcelCell(context, i, j, rowspan, colspan, row, column);
}
else
if (!(m_Table[i][j].RowSpan == 1 && m_Table[i][j].ColumnSpan == 1 && m_Table[i][j].RowSpanStartIndex == m_Table[i][j].RowIndex && m_Table[i][j].ColumnSpanStartIndex == m_Table[i][j].ColumnIndex)) //填充过,且不是单独的单元格,解开其所在的合并单元格,再填充
{
int mRow = m_Table[i][j].RowSpanStartIndex;
int mCol = m_Table[i][j].ColumnSpanStartIndex;
int mRSpan = m_Table[i][j].RowSpan;
int mCSpan = m_Table[i][j].ColumnSpan;
//解锁合并的单元格
for (int mRow1 = mRow; mRow1 < mRSpan + mRow; mRow1++)
{
for (int mCol1 = mCol; mCol1 < mCSpan + mCol; mCol1++)
{
string oldContext = m_Table[mRow][mCol].Context;
m_Table[mRow1][mCol1] = new TableForExcelCell(oldContext, mRow1, mCol1, 1, 1, mRow1, mCol1);
}
}
//重新填充要填充的单元格
m_Table[i][j] = new TableForExcelCell(context, i, j, rowspan, colspan, row, column);
}
else
{
m_Table[i][j] = new TableForExcelCell(context, i, j, rowspan, colspan, row, column);
}
}
}
}
此方法实现了类似填充单元格的功能。当遇到所填区域属于被合并过的单元格区域,会将原合并的单元格拆分开再进行填充。
然后,再手动拼接成string输出。
/// <summary>
/// 是否显示边框
/// </summary>
/// <param name="_border">显示边框的宽度</param>
/// <returns></returns>
public string TableToString(int _border)
{
StringBuilder sb = new StringBuilder();
string border = @"""" + _border + @"""";
sb.AppendFormat("<table border={0}>", border);
for (int i = 0; i < RowCount; i++)
{
sb.Append("<tr>");
for (int j = 0; j < ColumnCount; j++)
{
TableForExcelCell cell = this[i, j];
if (cell == null)
{
sb.Append("<td></td>");
}
else
{
if ((cell.RowIndex == cell.RowSpanStartIndex) && (cell.ColumnIndex == cell.ColumnSpanStartIndex))
{
string span = "";
if (cell.RowSpan > 1)
{
span += @" rowspan=""" + cell.RowSpan + @"""";
}
if (cell.ColumnSpan > 1)
{
span += @" colspan=""" + cell.ColumnSpan + @"""";
}
sb.AppendFormat("<td{1}>{0}</td>", cell.Context, span);
}
}
}
sb.Append("</tr>");
}
sb.Append("</table>");
return sb.ToString();
}
本方法的思路在于提供了公共的填充单元格的方法以及从TableForExcel类转化成string的方法,至于哪些数据需要合并等操作均在调用填充方法前按输出需要自行解决。