实际报表打印可能需要同时写入表格类型数据和报表主题、时间、单位等内容,因此需要同时处理单一零散数据和有规则的表格数据。通过改写InsertBlemDatatoBookmark方法,可以做到。(相关内容参考以前随笔)
方法全文如下:(包括说明)
参数:FileName--报表模板文件名称
savefilename--报表生成后另存文件名称
dt-报表的表格数据
has-报表的零散数据
introw-报表表格数据表格头所在模板行
public void InsertBlemDatatoBookmark(string FileName, System.Data.DataTable dt,
string savefilename, System.Collections.Hashtable has,int introw)
{
//打开文档
Microsoft.Office.Interop.Word.Document wDoc = null;
Microsoft.Office.Interop.Word.Application wApp = null;
this.OpenWordDoc(FileName, ref wDoc, ref wApp);
object oEndOfDoc = "http://www.cnblogs.com/Andmm/admin/file://endofdoc/";
object missing = System.Reflection.Missing.Value;
//查找表标签-枚举出所有非表格的标签(包含table的标签除外)
System.Collections.IEnumerator enu = wApp.ActiveDocument.Bookmarks.GetEnumerator();
Microsoft.Office.Interop.Word.Bookmark bk = null;
object tableobj = null;
while (enu.MoveNext())
{
bk = (Microsoft.Office.Interop.Word.Bookmark)enu.Current;
if (bk.Name.ToString().Trim().IndexOf("table") > -1)
{
tableobj = bk.Name.ToString(); break;
}
}
//写表数据-含table的标签
//unit对象定义
object unith = Microsoft.Office.Interop.Word.WdUnits.wdRow;//表格行方式
object extend = Microsoft.Office.Interop.Word.WdMovementType.wdExtend;/**////extend对光标移动区域进行扩展选择
object unitu = Microsoft.Office.Interop.Word.WdUnits.wdLine;//文档行方式,可以看成表格一行.不过和wdRow有区别
object unitp = Microsoft.Office.Interop.Word.WdUnits.wdParagraph;//段落方式,对于表格可以选择到表格行后的换车符,对于跨行合并的行选择,我能找到的最简单方式
if (tableobj != null)
{
//光标移到当前插入位置
wApp.ActiveDocument.Bookmarks.get_Item(ref tableobj).Select();
Microsoft.Office.Interop.Word.Table table = wApp.Selection.Tables[1];
//表格头的下一行
int r = introw+1;
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
table.Cell(r, j + 1).Range.Text = dt.Rows[i][j].ToString().Trim();
}//for
//准备插入新的空表行
//获取当前光标所在页码
object strpage1 = wApp.Selection.get_Information(WdInformation.wdActiveEndAdjustedPageNumber);
//新行
if (i + 1 < dt.Rows.Count)
{
table.Rows.Add(ref missing);
}
else
{
break;
}
object count = table.Rows.Count; ;//光标移动量
wApp.Selection.Move(ref unith, ref count);
//获取新行后当前页码
object strpage2 = wApp.Selection.get_Information(WdInformation.wdActiveEndAdjustedPageNumber);
//如页码不一致,需要插入新表头(这里是单行表头,复杂表头参见文后)
if (strpage2.ToString() != strpage1.ToString())
{//插入表头
wApp.Selection.Tables[1].Cell(introw, 1).Select();
wApp.Selection.HomeKey(ref unith, ref missing);
wApp.Selection.EndKey(ref unith, ref extend);
wApp.Selection.Copy();
wApp.Selection.Move(ref unith, ref count);
wApp.Selection.Paste();
r++;
}//if
//插入行+1
r++;
}
}
//写其他数据
if (has != null && has.Count > 0)
{
object tempobject = null;
//int length = 0;
foreach (System.Collections.DictionaryEntry d in has)
{
tempobject = d.Key.ToString();
if (wApp.ActiveDocument.Bookmarks.Exists(d.Key.ToString()))
{
wApp.ActiveDocument.Bookmarks.get_Item(ref tempobject).Select();
wApp.Selection.Text = d.Value.ToString();
//暂时屏蔽,取标签数据用的
//length = dt.Rows[0][strbook[i]].ToString().Length;
//wApp.ActiveDocument.Bookmarks.get_Item(ref tempobject).End = wApp.ActiveDocument.Bookmarks.get_Item(ref tempobject).End + length;
}
}
}
//收尾工作
object o = null;
object sFileName = savefilename;
if (wDoc.SaveFormat == (int)Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatDocument)
{
wDoc.Application.ActiveDocument.SaveAs(ref sFileName, ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing,
ref missing, ref missing,
ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing);
}
wDoc.Close(ref missing, ref missing, ref missing);
wApp.Quit(ref missing, ref missing, ref missing);
if (wDoc != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(wDoc);
wDoc = null;
}
if (wApp != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(wApp);
wApp = null;
}
GC.Collect();
}
#region 多行复杂表头的获取方法(简单的下移行复制是不无法复制复杂表头的,这应该是word的缺陷,必须要扩展到行尾)
////定位到表格第1单元格
//WApp.Selection.Tables[1].Cell(1, 1).Select();
////定位到第1个单元格第1个字符前
//WApp.Selection.HomeKey(ref unith, ref missing);
////扩展到行尾,选择表第1行
//WApp.Selection.EndKey(ref unith, ref extend);
////定义表格标题的行数量,titlerow为参数
//object strtitlerow=titlerow-1;
////移动光标选择第1行的末尾段落标记
//WApp.Selection.MoveDown(ref unitp, ref count, ref extend);
////选择下一行,因为合并的原因,如表格标题最后列是合并,只选择了2行的部分
// WApp.Selection.MoveDown(ref unitu, ref strtitlerow, ref extend);
////扩展到该行的末端,保证合并行能全部选择到
// WApp.Selection.EndKey(ref unith, ref extend);
////复制选择内容到剪贴板
// WApp.Selection.Copy();
////下面是移动光标到任何位置并粘贴内容.我程序中目的是到表格换页的时候自动插入下一页的表头.
//WApp.Selection.Tables[1].Cell(System.Convert.ToInt32(strRownum), 1).Select();
//WApp.Selection.HomeKey(ref unith, ref missing);
//WApp.Selection.Paste();
#endregion
--------------------------------------------------------------
事繁勿慌,事闲勿荒,有言必信,无欲则刚。
和若春风,肃若秋霜,取象于钱,外圆内方。
---顾炎培?
----------------------------------------------------------------