C#動態向Word模板插入表格
這幾天寫程式時遇到一個問題,就是需要將程式收集到使用者輸入的內容使用文件形式儲存下來並且在網路中進行傳輸,一開始使用的是PDF文件,因為他一旦編輯,幾乎不可修改。這就保證資訊的完整性和正確性。
最初使用的是itexSharp進行寫入,但是隨著使用者輸入資料量的增大發現問題,那就是需要寫大量的程式碼來控制寫入文字的格式和字型等資訊,通過建立模板方式程式碼也不太好寫,而且一旦資料量較大的話造成最終產生的xx.pdf檔案也是較大,也不利於在網路中進行傳輸,同時其靈活性較差,如果要去生成文件的版式發生改變就需要重新寫程式碼來改變文件的佈局。
最後決定使用Word文件進行編輯,雖然Word文件的安全性不如pdf但是因為整個檔案的傳輸過程中使用的是內網,因此也沒有多大的問題。而且使用Word模板操作,其靈活性更好,假設在傳入引數不變情況下,需要改變最終生成Word版式時只需要修改Word模板即可,而不需要重新寫程式碼。
廢話不多說,看程式碼,下面這個Report類是從網上找到的一個Word模板操作類,更改名稱空間後即可直接使用。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Word; namespace 公共方法 { public class Report { private _Application wordApp = null; private _Document wordDoc = null; public _Application Application { get { return wordApp; } set { wordApp = value; } } public _Document Document { get { return wordDoc; } set { wordDoc = value; } } //通過模板建立新文件 public void CreateNewDocument(string filePath) { killWinWordProcess(); wordApp = new ApplicationClass(); wordApp.DisplayAlerts = WdAlertLevel.wdAlertsNone; wordApp.Visible = false; object missing = System.Reflection.Missing.Value; object templateName = filePath; wordDoc = wordApp.Documents.Open(ref templateName, 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); } //儲存新檔案 public void SaveDocument(string filePath) { object fileName = filePath; object format = WdSaveFormat.wdFormatDocument;//儲存格式 object miss = System.Reflection.Missing.Value; wordDoc.SaveAs(ref fileName, ref format, ref miss, ref miss, ref miss, ref miss, ref miss, ref miss, ref miss, ref miss, ref miss, ref miss, ref miss, ref miss, ref miss, ref miss); //關閉wordDoc,wordApp物件 object SaveChanges = WdSaveOptions.wdSaveChanges; object OriginalFormat = WdOriginalFormat.wdOriginalDocumentFormat; object RouteDocument = false; wordDoc.Close(ref SaveChanges, ref OriginalFormat, ref RouteDocument); wordApp.Quit(ref SaveChanges, ref OriginalFormat, ref RouteDocument); }
<span style="white-space:pre"> //插入表格,bookmark書籤 public Table InsertTable(string bookmark, int rows, int columns, float width) { object miss = System.Reflection.Missing.Value; object oStart = bookmark; Range range = wordDoc.Bookmarks.get_Item(ref oStart).Range;//表格插入位置 Table newTable = wordDoc.Tables.Add(range, rows, columns, ref miss, ref miss); //設定表的格式 newTable.Borders.Enable = 1; //允許有邊框,預設沒有邊框(為0時報錯,1為實線邊框,2、3為虛線邊框,以後的數字沒試過) newTable.Borders.OutsideLineWidth = WdLineWidth.wdLineWidth050pt;//邊框寬度 if (width != 0) { newTable.PreferredWidth = width;//表格寬度 } newTable.AllowPageBreaks = false; return newTable; }</span>
//設定表格內容對齊方式 Align水平方向,Vertical垂直方向(左對齊,居中對齊,右對齊分別對應Align和Vertical的值為-1,0,1)
public void SetParagraph_Table(Word.Table table, int Align, int Vertical)
{
switch (Align)
{
case -1: table.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphLeft; break;//左對齊
case 0: table.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter; break;//水平居中
case 1: table.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphRight; break;//右對齊
}
switch (Vertical)
{
case -1: table.Range.Cells.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalTop; break;//頂端對齊
case 0: table.Range.Cells.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter; break;//垂直居中
case 1: table.Range.Cells.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalBottom; break;//底端對齊
}
}
//設定表格字型
public void SetFont_Table(Word.Table table, string fontName, double size)
{
if (size != 0)
{
table.Range.Font.Size = Convert.ToSingle(size);
}
if (fontName != "")
{
table.Range.Font.Name = fontName;
}
}
//是否使用邊框,n表格的序號,use是或否
public void UseBorder(int n, bool use)
{
if (use)
{
wordDoc.Content.Tables[n].Borders.Enable = 1; //允許有邊框,預設沒有邊框(為0時報錯,1為實線邊框,2、3為虛線邊框,以後的數字沒試過)
}
else
{
wordDoc.Content.Tables[n].Borders.Enable = 2; //允許有邊框,預設沒有邊框(為0時報錯,1為實線邊框,2、3為虛線邊框,以後的數字沒試過)
}
}
//給表格插入一行,n表格的序號從1開始記
public void AddRow(int n)
{
object miss = System.Reflection.Missing.Value;
wordDoc.Content.Tables[n].Rows.Add(ref miss);
}
//給表格新增一行
public void AddRow(Word.Table table)
{
object miss = System.Reflection.Missing.Value;
table.Rows.Add(ref miss);
}
//給表格插入rows行,n為表格的序號
public void AddRow(int n, int rows)
{
object miss = System.Reflection.Missing.Value;
Word.Table table = wordDoc.Content.Tables[n];
for (int i = 0; i < rows; i++)
{
table.Rows.Add(ref miss);
}
}
//給表格中單元格插入元素,table所在表格,row行號,column列號,value插入的元素
public void InsertCell(Word.Table table, int row, int column, string value)
{
table.Cell(row, column).Range.Text = value;
}
//給表格中單元格插入元素,n表格的序號從1開始記,row行號,column列號,value插入的元素
public void InsertCell(int n, int row, int column, string value)
{
wordDoc.Content.Tables[n].Cell(row, column).Range.Text = value;
}
//給表格插入一行資料,n為表格的序號,row行號,columns列數,values插入的值
public void InsertCell(int n, int row, int columns, string[] values)
{
Word.Table table = wordDoc.Content.Tables[n];
for (int i = 0; i < columns; i++)
{
table.Cell(row, i + 1).Range.Text = values[i];
}
}
}
}
在使用這個類的時候需要新增COM引用MicroSoft Word 11.0 Object Library,因為我用的是Office 2003所以匯入就是11.0,根據自己電腦上的Office版本選擇匯入的版本即可,這時候還需要修改匯入動態庫的互操作型別改為false,否則也是會報錯的。
這個類在使用的時候,只能當做一箇中間類,具體操作Word模板的方法可以再根據模板的不同,呼叫這個類中的相應的方法對模板進行修改,這就很好的保證了程式碼的複用性,從而避免了大量重複的程式碼重寫。
同時這個類在對錶格進行操作時可以動態獲取模板中的表格物件,例如在對某個表格插入一行時可以呼叫 AddRow(int n)方法,這個方法中int型別資料n代表了模板中的第幾個表格n的值從1開始。
在程式中需要根據資料量的不同動態插入表格,可以先將表格的表頭插入模板中然後由資料數量確定插入表格的行數和列數,然後向這些單元格中插入資料。
例如:有一個list物件,動態插入一個有9列的表格中,表格的行數由list元素數量確定。具體程式碼如下:
<span style="white-space:pre"> </span>int row = list.Count%9>0?list.Count/9+1:list.Count/9;
for (int i = 3; i < row+3; i++)
{
report.AddRow(4);
for (int j = 1; j <= 9; j++)
{
if (k < list.Count)
{
report.InsertCell(4, i, j, list[k].ToString());
k++;
}
}
}
這段程式碼中i的初始值之所以是3是因為我要從那個表格的第三行進行插入資料,AddRow(4)是代表向第四個表格中插入行。
InsertCell是向單元格中插入資料的方法,該方法的第一個引數4代表向第四個單元格插入資料,i,j分別代表單元格的行號和列號,他們的值都是從1開始。這段程式碼就完成了向模板中動態插入表格,並且向表格中插入相應的資料。
同時這個方法還有建立表格的方法,這個方法返回的值是一個Table物件,在後面的插入行,向表格中插入值得方法中他也可以作為引數進行傳遞,同樣能達到動態向表格插入行和資料的方法。