2009年3月16日 星期一

[資訊] C#讀寫MS word, Excel

「讀」excel是件很容易的事情,至少在C#是這樣子


可以使用的方法很多


 


最常見的就是如資料庫一般的讀檔案,使用olb DB來開檔案


要import oleDB


using System.Data;
using System.Data.OleDb;


 


           
            //   如果Excel中的第一列為欄名,則寫成
            string sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\awardProgram\\reference.xls;Extended Properties=\"Excel 8.0;HDR=YES\"";

            //string sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\awardProgram\\reference.xls;Extended Properties=\"Excel 8.0;HDR=NO\"";

            OleDbConnection cn = new OleDbConnection();
            cn.ConnectionString = sConnectionString;
            cn.Open();

            string sSQL = "SELECT * FROM [awardReference$]"; //[_____$] 底線部份是加上sheet name
            OleDbCommand cmd = cn.CreateCommand();
            cmd.CommandText = sSQL;
            OleDbDataReader DR = cmd.ExecuteReader();
            while (DR.Read())
            {
                Console.WriteLine(DR[7].ToString());//讀取第7欄的資訊並把他印出來
            }
            cn.Close();


因為他是一個row 一個row去讀取的,所以只能這個樣子


當然如果你會寫SQL語法的話,可以在裡面進行一些編寫,可以只讀取固定的欄位,不會的話就照抄吧~


(以後有空來教一下簡單的sql語法好了)


 


---------------------------------------------------------------------------------------


 


雖然這次程式沒有用到寫excel的部份,不過我其實有查啦~~


using Microsoft.Office.Core;  //需要在Project-->add reference中加入
using Microsoft.Office.Interop.Excel;
using Excel = Microsoft.Office.Interop.Excel;



    object missing=System.Reflection.Missing.Value;
    ApplicationClass app=new ApplicationClass();

     //開啟此檔案
     Workbook workbook=app.Workbooks.Open(filename,missing,missing,
       missing,missing,missing,missing,missing,
     missing,missing,missing,missing,missing,missing,missing);

     //讀某個sheet
     Worksheet sheet=(Worksheet)workbook.Worksheets[sheetname];

     //讀某個Range
     Range range=sheet.get_Range("A1","A1");

     //寫入值
     range.set_Value(missing,"xxxxxx");


這部份我沒有實際用到~~大家可以試試~個人覺得應該是可以的,因為他和寫入word的語法很相似


----------------------------------------------------------------------------------------------------------------------


讀寫word的話:最麻煩的就是他要用range的方式,讓我很不習慣~


 Microsoft.Office.Interop.Word.ApplicationClass oWord = new Word.ApplicationClass();
            oWord.Visible = true;
            Word.Documents oDocs = oWord.Documents;
            object oFile = "E:\\test\\doc1.doc";


            object oMissing = System.Reflection.Missing.Value;
            Word._Document oDoc = oDocs.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);


 


            //報表結束,存檔結束


            oDoc.SaveAs(ref oFile, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
            oDoc.Close(ref oMissing, ref oMissing, ref oMissing);//關閉
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oDoc);
            oDoc = null;
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oDocs);
            oDocs = null;
            oWord.Quit(ref oMissing, ref oMissing, ref oMissing);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oWord);
            oWord = null;


 


中間你可以使用各種方式來進行…


主要的概念是一個Range()的概念(意思就是你的滑鼠選了哪些部份啦


然後再用range.insertAfter, insertBefore的方式來add text....


個人建議寫的時候灌一個英文版的word...可以比較快速查到一些想要的函式名


 


最後這邊放了一些我用到的東西


 oDoc.PageSetup.TopMargin = (float)(54.5);        //設定邊界 //top 可以改成left, right, bottom等


插入分頁符號


object Type = Word.WdBreakType.wdSectionBreakNextPage;//分頁符號 wdSectionBreakNextPage可以換
 range.InsertBreak(ref Type);


 


字體改變:


range.Font.Size = 12;
range.Font.Name = "標楷體";


 


改變對齊方式


range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphLeft;//靠左


改變文字間距


range.ParagraphFormat.LineSpacingRule = WdLineSpacing.wdLineSpaceSingle;//單行間距


range.ParagraphFormat.LineSpacingRule = WdLineSpacing.wdLineSpaceExactly;//固定行高
range.ParagraphFormat.LineSpacing = 18;//18 point


調整第二行縮排


range.ParagraphFormat.TabHangingIndent(2); //可以寫負數,就是往前調


第一行縮排就是


tempRange.ParagraphFormat.TabIndent(2);


 


取得目前的字數(不是計算整份文件的字數喔~因為有一些特殊字元,所以不會一樣,這是用來設定range用的


int num= oDoc.Characters.Count; 


 


 


其他用到的字體變化:


range.Font.Position = 12;// 應該是用來指顯示區是多少pt
range.Font.Kerning = 12;//字元間距壓縮微調
range.Font.Subscript = 12; //類似下標文字
range.Font.Position = 12; 文字上移,可改成負數,就是下移
range.Font.Scaling = 12;


這些其實都是在格式-->字型 裡面可以看到…不過中文版的word很難看懂這些意義~所以建議用英文版word比較容易對照


最後附上一小段我自己寫的插入頁碼的原始程式碼,希望有高人來教我


  private void insertPageNumber(Word._Document oDoc){

            Word.Section section = oDoc.Sections[1];
           
                object fieldEmpty = Word.WdFieldType.wdFieldEmpty;
                object autoText = "Page";  //頁碼
                object autoNumPage = "NUMPAGES";//頁數
                //object autoText = "AUTOTEXT  \"Page X of Y\" ";
                object preserveFormatting = true;

                Range footer = section.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
               
                //footer.AutoFormat();
                footer.Fields.Add(section.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range, ref fieldEmpty, ref autoText, ref preserveFormatting);
                footer.InsertBefore("第");
                footer.InsertAfter("頁,共頁");


                footer.SetRange(29,29);//直接指定位置。
//這邊我是用爆力法來寫,歡迎有強者來教我正確的寫法
                footer.Fields.Add(footer, ref fieldEmpty, ref autoNumPage, ref preserveFormatting);
                 section.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;//置中對齊

     
        }


 


----------------


後記:


個人覺得C#寫的這些設計說直觀很直觀啦~~有很多部份…都是word按幾個鍵,他就需要出現幾個dot


但又有很多地方很不直觀…弄得很麻煩~


而且很明顯這是多人合寫的api,因為有很多的變數命名很不一致~使用方式也很不一樣


ex:font.size=12;font.name="新細明體";


但不是絕對,有一些地方是當變數傳進去,如


range.ParagraphFormat.TabHangingIndent(2);等


且get,set等變數命名方式都沒有用到…第一次用真的會讓人不習慣


 


---


此文章下一篇:c#插入word文件頁碼 分段篇


沒有留言:

張貼留言