找回密碼 或 安全提問
 註冊
|註冊|登錄

伊莉討論區

搜索
感激所有對伊莉作出奉獻的人尊貴會員無限看帖不用回覆搞笑、娛樂、精彩的影片讓你看
gefc2刀劍神域我的英雄強姦出包王女名偵探柯
代表隊暖暖日記riojjbk 072校花燕七愛吃龍騎的天

休閒聊天興趣交流學術文化旅遊交流飲食交流家庭事務PC GAMETV GAME
熱門線上其他線上感情感性寵物交流家族門派動漫交流貼圖分享BL/GL
音樂世界影視娛樂女性頻道潮流資訊BT下載區GB下載區下載分享短片
電腦資訊數碼產品手機交流交易廣場網站事務長篇小說體育運動時事經濟
上班一族博彩娛樂

[簡]莫名成為邪龍的五

[繁]魔王陛下,RETRY

[繁]海賊王 魚人島篇

[繁]被逐出隊伍的治癒

[繁]青春之箱06-

[繁]戰國妖狐27-
C & C++ 語言C# 語言Visual Basic 語言PHP 語言JAVA 語言
查看: 10656|回復: 13
打印上一主題下一主題

[分享]分享一些程式寫作的小技巧[複製鏈接]

Rank: 2Rank: 2

帖子
541
積分
212 點
潛水值
13707 米
跳轉到指定樓層
樓主
發表於 2015-9-11 10:56 AM|只看該作者|正序瀏覽
若瀏覽伊莉的時侯發生問題或不正常情況,請使用Internet Explorer(I.E)。
這是一個將 DataGridView 相關的一些常用到的功能,作一些小小分享,其中就包括轉成EXCEL檔案、列印等。
其中也有一些平常設計程式會用到的小技巧,諸如資料模組的設計,擴充法、資料型別的轉換等等,給大家參考。
這是Form1.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Drawing.Printing;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Runtime.InteropServices;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using System.Windows.Forms;
  13. using Excel = Microsoft.Office.Interop.Excel;

  14. namespace ListToDataGridView
  15. {
  16.     public partial class Form1 : Form
  17.     {
  18.         //通常定義欄位都是以private為主
  19.         private List<PersonModel> person;
  20.         private string toExcelString = "";
  21.         private Timer timer;
  22.         //定義常數
  23.         private const int WM_CLOSE = 0x10;
  24.         public Form1()
  25.         {
  26.             InitializeComponent();
  27.         }
  28.         //API
  29.         [DllImport("User32.dll", EntryPoint = "FindWindow", SetLastError = true, CharSet = CharSet.Auto)]
  30.         public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
  31.         [DllImport("User32.dll", EntryPoint = "PostMessage", SetLastError = true, CharSet = CharSet.Auto)]
  32.         public static extern bool PostMessage(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam);

  33.         private void Form1_Load(object sender, EventArgs e)
  34.         {
  35.             //建構時一次加入3筆資料
  36.             person = new List<PersonModel>()
  37.             {
  38.                 new PersonModel
  39.                 {
  40.                     Name = "王大維",
  41.                     ID = "B122111111",
  42.                     Birthday = "19680705",
  43.                     TEL = "07-23593512",
  44.                     CellPhone = "0982-333-333",
  45.                     Address = "高雄市苓雅區中華西路二段451號" ,
  46.                     EMail = "daviwang@msa.hinet.net"
  47.                 },
  48.                 new PersonModel
  49.                 {
  50.                     Name = "姜中華",
  51.                     ID = "C122221221",
  52.                     Birthday = "19771025",
  53.                     TEL = "04-23257066",
  54.                     CellPhone = "0952-666-666",
  55.                     Address = "台中市北屯區中西三路1026號",
  56.                     EMail = "hwa661025888@yahoo.com.tw"
  57.                 },
  58.                 new PersonModel
  59.                 {
  60.                     Name = "張小明",
  61.                     ID = "A122331331",
  62.                     Birthday = "19780630",
  63.                     TEL = "02-25805632",
  64.                     CellPhone = "0988-999-999",
  65.                     Address = "台北市大安區復興南路一段203號10樓之16",
  66.                     EMail = "ming53621107@gmail.com"
  67.                 }
  68.             };

  69.             //或是後來再加入1筆資料
  70.             person.Add(new PersonModel
  71.                 {
  72.                     Name = "李維勳",
  73.                     ID = "T122551551",
  74.                     Birthday = "19750630",
  75.                     TEL = "02-23231122",
  76.                     CellPhone = "0938-777-777",
  77.                     Address = "台北市松山區信義路二段300號11樓之1",
  78.                     EMail = "waishin@dodogogo.com"
  79.                 });
  80.             
  81.             //實際應用時也許會像這樣
  82.             /*
  83.             person.Add(new PersonModel
  84.             {
  85.                 Name = textBox1.Text,
  86.                 ID = textBox2.Text,
  87.                 Birthday = textBox3.Text,
  88.                 TEL = textBox4.Text,
  89.                 CellPhone = textBox5.Text,
  90.                 Address = textBox6.Text,
  91.                 EMail = textBox7.Text
  92.             });  */
  93.             //=============================================================
  94.             //這段程式碼是將 List 放到 dataGridView1 裡
  95.             //這裡我在 ExtensionUtility.cs 這個類別裡寫的一個擴充方法
  96.             dataGridView1.DataSource = person.ToBindingSource<PersonModel>();
  97.             //=============================================================

  98.             //=============================================================
  99.             //設定欄位寬度,這段也可以放到dataGridView1_DataBindingComplete裡面
  100.             for (int i = 0; i < dataGridView1.ColumnCount; i++)
  101.             {
  102.                 dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
  103.             }
  104.             //=============================================================
  105.         }

  106.         //匯出EXCEL檔案功能按鈕
  107.         private void toExcelButton_Click(object sender, EventArgs e)
  108.         {
  109.             if (toExcelString == "") return;
  110.             //為了避免相互干擾,會強制關閉執行中EXCEL
  111.             initailExcel();
  112.             //所以要確認其它開啟的EXCEL檔案已經存檔並關閉。
  113.             Excel.Application xlApplication = new Excel.Application();
  114.             Excel.Workbook workBook = null;
  115.             Excel.Worksheet first_sheet = null;
  116.             Excel.Range tmprng = null;
  117.             string xlfilename = "";
  118.             FolderBrowserDialog fd = new FolderBrowserDialog();
  119.             if (fd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  120.             {
  121.                 if (fd.SelectedPath.Substring(fd.SelectedPath.Length-1, 1) == @"\")
  122.                     //如果是選根目錄
  123.                     xlfilename = fd.SelectedPath + @"(" + convertDate(DateTime.Now) + ")-個人資料(明細表).xlsx";
  124.                 else
  125.                     //選子目錄
  126.                     xlfilename = fd.SelectedPath + @"\(" + convertDate(DateTime.Now) + ")-個人資料(明細表).xlsx";
  127.             }
  128.             else
  129.             {
  130.                 return;
  131.             }
  132.             try
  133.             {
  134.                 //EXCEL檔案如果已經存在就直接刪除
  135.                 if (File.Exists(xlfilename)) { File.Delete(xlfilename); }
  136.                 //建立新的EXCEL檔案
  137.                 workBook = xlApplication.Workbooks.Add();
  138.                 first_sheet = workBook.Sheets[1] as Excel.Worksheet;
  139.                 //將文字複製到剪貼簿
  140.                 Clipboard.SetText(toExcelString, TextDataFormat.UnicodeText);
  141.                 //將C到E欄和G欄設定為文字格式並靠右對齊
  142.                 tmprng = first_sheet.Range["C:E"];
  143.                 tmprng.NumberFormat = "@";
  144.                 tmprng.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignRight;
  145.                 //在A1貼上剪貼簿上的內容
  146.                 first_sheet.Paste(first_sheet.Range["A1", Type.Missing], false);
  147.                 first_sheet.Name = "服務事項明細表";
  148.                 //設定自動欄寬
  149.                 first_sheet.Cells.EntireColumn.AutoFit();
  150.                 //設定自動篩選
  151.                 tmprng = first_sheet.get_Range("A1", "A1");
  152.                 tmprng.AutoFilter(1, Type.Missing, Excel.XlAutoFilterOperator.xlAnd, Type.Missing, true);
  153.                 //不詢問直接覆蓋原有檔案
  154.                 xlApplication.DisplayAlerts = false;
  155.                 //存檔為 EXCEL 2007 格式
  156.                 workBook.SaveAs(xlfilename, Excel.XlFileFormat.xlWorkbookDefault);
  157.             }
  158.             catch (Exception ex)
  159.             {
  160.                 //這一段是秀出錯誤訊息並且5秒鐘後自動關閉
  161.                 StartTimerKillMessageBox(5);
  162.                 MessageBox.Show(ex.Message + ex.ToString(), "MessageBox");
  163.             }
  164.             finally
  165.             {
  166.                 //釋放掉一些資源的程式碼
  167.                 NAR(tmprng);
  168.                 NAR(first_sheet);
  169.                 NAR(workBook);
  170.                 xlApplication.Quit();
  171.                 NAR(xlApplication);
  172.                 GC.Collect();
  173.                 if (File.Exists(xlfilename)) MessageBox.Show("匯出成功!!");

  174.             }
  175.         }

  176.         //列印功能按鈕
  177.         private void toPrinter_Click(object sender, EventArgs e)
  178.         {
  179.             if (toExcelString == "") return;
  180.             string tmpstr = "";
  181.             string[] ss = System.Text.RegularExpressions.Regex.Split(toExcelString, "\r\n");
  182.             foreach (string s in ss)
  183.             {   //以下這段程式是將文字稍作排版
  184.                 if (s.Length < 5) continue;
  185.                 string[] sv = System.Text.RegularExpressions.Regex.Split(s, "\t");
  186.                 if (sv.Length == 7)
  187.                 {
  188.                     tmpstr += sv[0] + new String(' ', 12 - ChtStr_Lenght(sv[0]));
  189.                     tmpstr += sv[1] + new String(' ', 11 - ChtStr_Lenght(sv[1]));
  190.                     tmpstr += sv[2] + new String(' ', 11 - ChtStr_Lenght(sv[2]));
  191.                     tmpstr += sv[3] + new String(' ', 16 - ChtStr_Lenght(sv[3]));
  192.                     tmpstr += sv[4] + new String(' ', 16 - ChtStr_Lenght(sv[4]));
  193.                     tmpstr += sv[5] + new String(' ', 40 - ChtStr_Lenght(sv[5]));
  194.                     tmpstr += sv[6] + new String(' ', 28 - ChtStr_Lenght(sv[6])) + "\r\n";
  195.                 }
  196.             }
  197.             PrintDocument p = new PrintDocument();
  198.             //把版面設定成橫印
  199.             p.DefaultPageSettings.Landscape = true;
  200.             p.PrintPage += delegate(object sender1, PrintPageEventArgs e1)
  201.             {   //這個列印程式只能印出第一頁,如果要印出多頁,這段程式要做修改
  202.                 e1.Graphics.DrawString(tmpstr, new Font("標楷體", 11),
  203.                                        new SolidBrush(Color.Black),
  204.                                        new RectangleF(25, 50, p.DefaultPageSettings.PrintableArea.Height,
  205.                                        p.DefaultPageSettings.PrintableArea.Width));

  206.             };
  207.             try
  208.             {
  209.                 p.Print();
  210.             }
  211.             catch (Exception ex)
  212.             {
  213.                 throw new Exception("列印出錯:", ex);
  214.             }
  215.         }

  216.         private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
  217.         {
  218.             //每次DataBinding完成時都將person這個List轉成PersonExcelModel這個模組型態(LINQ語法)
  219.             //並且輸出成以TAB相隔的字串,方便貼到EXCEL工作表上
  220.             //其實這一整段基本上是可以放在Button_Click裡面的
  221.             toExcelString = "姓名\t證號\t生日\t電話\t手機\t地址\t電郵\r\n";

  222.             //這個是LINQ語法,我個人覺得是很好用東東
  223.             //=============================================================
  224.             var personexcel = from p in person
  225.                             group p by new {
  226.                                 p.Name,
  227.                                 p.ID,
  228.                                 p.Birthday,
  229.                                 p.TEL,
  230.                                 p.CellPhone,
  231.                                 p.Address,
  232.                                 p.EMail
  233.                             } into rs
  234.                             select new PersonExcelModel()
  235.                             {
  236.                                 姓名 = rs.Key.Name,
  237.                                 證號 = rs.Key.ID,
  238.                                 生日 = rs.Key.Birthday,
  239.                                 電話 = rs.Key.TEL,
  240.                                 手機 = rs.Key.CellPhone,
  241.                                 地址 = rs.Key.Address,
  242.                                 電郵 = rs.Key.EMail
  243.                             };
  244.             //=============================================================

  245.             //所以personexcel現在已經是PersonExcelModel這種形態了
  246.             foreach (var item in personexcel)
  247.             {
  248.                 toExcelString += item.ToString(); //這裡應用的就是之前複寫的ToString()方法
  249.             }
  250.         }

  251.         //啟動關閉訊息框
  252.         public void StartTimerKillMessageBox(int sec, string msg = "MessageBox")
  253.         {
  254.             timer = new Timer();
  255.             timer.Interval = sec * 1000; //等sec秒
  256.             timer.Tag = msg;
  257.             timer.Tick += new EventHandler(Timer_CloseMessageBox);
  258.             timer.Start();
  259.         }

  260.         public void Timer_CloseMessageBox(object sender, EventArgs e)
  261.         {
  262.             KillMessageBox(Convert.ToString(((Timer)sender).Tag));
  263.             //停止Timer
  264.             ((Timer)sender).Stop();
  265.         }

  266.         public void KillMessageBox(string msg)
  267.         {
  268.             //依MessageBox的標題,找出MessageBox的視窗
  269.             IntPtr ptr = FindWindow(null, msg);
  270.             if (ptr != IntPtr.Zero)
  271.             {
  272.                 //找到則關閉MessageBox視窗
  273.                 PostMessage(ptr, WM_CLOSE, UIntPtr.Zero, IntPtr.Zero);
  274.             }
  275.         }

  276.         //傳回自訂格式的日期
  277.         public string convertDate(DateTime dt)
  278.         {
  279.             return dt.Year.ToString("0000") + dt.Month.ToString("00") + dt.Day.ToString("00");
  280.         }

  281.         //傳回有中文的字串的真實長度
  282.         public int ChtStr_Lenght(string a_SrcStr)
  283.         {
  284.             byte[] l_byte = System.Text.Encoding.Default.GetBytes(a_SrcStr);
  285.             return l_byte.Length;
  286.         }

  287.         //釋放占用的資源
  288.         public void NAR(object sender)
  289.         {
  290.             try
  291.             {
  292.                 if (sender != null)
  293.                 {
  294.                     while (Marshal.ReleaseComObject(sender) > 0) ;
  295.                 }
  296.             }
  297.             finally
  298.             { sender = null; }
  299.         }
  300.         public void initailExcel()
  301.         {
  302.             //檢查PC有無Excel在執行,有的話強制關閉。
  303.             foreach (var item in System.Diagnostics.Process.GetProcesses())
  304.             {
  305.                 if (item.ProcessName.ToUpper() == "EXCEL")
  306.                 {
  307.                     item.Kill();
  308.                     item.WaitForExit();
  309.                 }
  310.             }
  311.         }
  312.     }
  313. }
複製代碼
這是DataModel.cs,用來設計資料的模組
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;

  6. namespace ListToDataGridView
  7. {
  8.     class PersonModel : IEquatable<PersonModel>
  9.     {
  10.         public string Name { get; set; }
  11.         public string ID { get; set; }
  12.         public string Birthday { get; set; }
  13.         public string TEL { get; set; }
  14.         public string CellPhone { get; set; }
  15.         public string Address { get; set; }
  16.         public string EMail { get; set; }

  17.         //IEquatable這個介面需要實作Equals這個方法
  18.         public bool Equals(PersonModel other)
  19.         {
  20.             return this.ID.Equals(other.ID);
  21.         }
  22.     }

  23.     class PersonExcelModel : IEquatable<PersonExcelModel>
  24.     {
  25.         public string 姓名 { get; set; }
  26.         public string 證號 { get; set; }
  27.         public string 生日 { get; set; }
  28.         public string 電話 { get; set; }
  29.         public string 手機 { get; set; }
  30.         public string 地址 { get; set; }
  31.         public string 電郵 { get; set; }

  32.         //IEquatable這個介面需要實作Equals這個方法
  33.         public bool Equals(PersonExcelModel other)
  34.         {   
  35.             return this.證號.Equals(other.證號);
  36.         }

  37.         //再寫一個多載方法可以和PersonModel做比對
  38.         public bool Equals(PersonModel other)
  39.         {
  40.             return this.證號.Equals(other.ID);
  41.         }

  42.         //這裡我們複寫ToString()這個方法,以便讓它可以符合輸出到EXCEL的需求
  43.         public override string ToString()
  44.         {
  45.             return this.姓名 + "\t" + this.證號 + "\t" + this.生日
  46.                         + "\t" + this.電話 + "\t" + this.手機
  47.                         + "\t" + this.地址 + "\t" + this.電郵 + "\r\n";
  48.         }
  49.     }
  50. }
複製代碼
這是ExtensionUtility.cs,裡面裝了一個把List轉成BindingSource的擴充方法
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows.Forms;

  8. namespace ListToDataGridView
  9. {
  10.     public static class ExtensionUtility
  11.     {
  12.         //擴充方法,有興趣自己找資料研究,可以先看看MSDN的說明
  13.         //https://msdn.microsoft.com/zh-tw/library/bb383977.aspx
  14.         public static BindingSource ToBindingSource<TSource>(this IList<TSource> data)
  15.         {
  16.             var bindingList = new BindingList<TSource>(data);
  17.             return new BindingSource(bindingList, null);

  18.         }
  19.     }
  20. }
複製代碼
請大家不吝指教...
瀏覽完整內容,請先 註冊登入會員
分享分享0收藏收藏1支持支持1
如果發覺自己無法使用一些功能或出現問題,請按重新整理一次,並待所有網頁內容完全載入後5秒才進行操作。

使用道具檢舉

帖子
10
積分
5 點
潛水值
11930 米
14
發表於 2021-1-2 03:59 AM|只看該作者
如果瀏覽伊莉時速度太慢或無法連接,可以使用其他分流瀏覽伊莉,www01.eyny.com(02,03)。
太神啦
感謝大大的分享
如果瀏覽伊莉時速度太慢或無法連接,可以使用其他分流瀏覽伊莉,www01.eyny.com(02,03)。

使用道具檢舉

Rank: 1

帖子
63
積分
59 點
潛水值
10104 米
13
發表於 2020-8-27 10:55 PM|只看該作者
回覆中加入附件並不會使你增加積分,請使用主題方式發佈附件。

使用道具檢舉

帖子
39
積分
29 點
潛水值
3655 米
12
發表於 2020-4-15 02:18 PM|只看該作者
謝謝大大分享,收下使用

使用道具檢舉

Rank: 2Rank: 2

帖子
84
積分
504 點
潛水值
8934 米
11
發表於 2016-3-13 09:08 PM|只看該作者
如果你忘記伊莉的密碼,請在登入時按右邊出現的 '找回密碼'。輸入相關資料後送出,系統就會把密碼寄到你的E-Mail。
小弟也是新手,最近在研究Kendo UI ,發現他蠻好用的,可以直接幫你把Girid的資料產出成Excel,完全不用寫程式,你可以試試看唷




使用道具檢舉

帖子
8
積分
5 點
潛水值
13580 米
10
發表於 2016-3-4 08:21 AM|只看該作者
分享使你變得更實在,可以使其他人感到快樂,分享是我們的動力。今天就來分享你的資訊、圖片或檔案吧。
不建議這樣操作Excel
樓上ODBC方式較佳
不然也可找open source有可以直接生成excel檔案的方法
如果發覺自己無法使用一些功能或出現問題,請按重新整理一次,並待所有網頁內容完全載入後5秒才進行操作。

使用道具檢舉

  小學生(200/1000)

孤單落葉

Rank: 2Rank: 2

帖子
300
積分
309 點
潛水值
23142 米
9
發表於 2016-2-26 04:13 PM|只看該作者
回覆中加入附件並不會使你增加積分,請使用主題方式發佈附件。
很棒呀!!!
我也算是C#新手八= =
剛好目前有遇到~DATAGREADVIEW TO EXCEL~
完全就是我的需要阿!!

使用道具檢舉

帖子
309
積分
0 點
潛水值
11174 米
8
發表於 2016-2-24 10:35 PM|只看該作者

使用道具檢舉

Enjoyeyny51 該用戶已被刪除
7
發表於 2015-12-25 12:29 AM|只看該作者
成為伊莉的版主,你將獲得更高級和無限的權限。把你感興趣的版面一步步地發展和豐盛,那種滿足感等著你來嚐嚐喔。
這範例解說真不錯
剛好最近有需要用到類似的功能
範例先收下當參考了

謝謝大大分享^^

使用道具檢舉

帖子
309
積分
0 點
潛水值
11174 米
6
發表於 2015-11-19 09:00 PM|只看該作者
還不錯的介紹

程式的基礎架構都有
當然純看CODE 會有一些基礎會比較好
如有用到INTERFACE 等技巧




成為伊莉的版主,你將獲得更高級和無限的權限。把你感興趣的版面一步步地發展和豐盛,那種滿足感等著你來嚐嚐喔。

使用道具檢舉

Rank: 2Rank: 2

帖子
416
積分
388 點
潛水值
8472 米
5
發表於 2015-10-1 01:22 PM|只看該作者
最近剛好從C++跳過來
很多都還看不懂

感謝大大的分享
讓我有學習的地方
若瀏覽伊莉的時侯發生問題或不正常情況,請使用Internet Explorer(I.E)。

使用道具檢舉

Rank: 2Rank: 2

帖子
541
積分
212 點
潛水值
13707 米
4
發表於 2015-9-24 12:42 AM|只看該作者
若新密碼無法使用,可能是數據未更新。請使用舊密碼看看。
smallanan 發表於 2015-9-24 12:04 AM
下載: 訪客無法瀏覽下載點,請先 註冊登入會員

個人會比較建議如果依照datagridview一模一樣的方式匯出excel檔案的話

使用odbc效率會比較好(而且不用安 ...

哈哈,我說怎麼都沒人回應呢?感謝您的指教!!
...
瀏覽完整內容,請先 註冊登入會員
如果發覺自己無法使用一些功能或出現問題,請按重新整理一次,並待所有網頁內容完全載入後5秒才進行操作。

使用道具檢舉

smallanan 該用戶已被刪除
3
發表於 2015-9-24 12:04 AM|只看該作者
若有安裝色情守門員,可用無界、自由門等軟件瀏覽伊莉。或使用以下網址瀏覽伊莉: http://www.eyny.com:81/index.php
個人會比較建議如果依照datagridview一模一樣的方式匯出excel檔案的話

使用odbc效率會比較好(而且不用安裝office)

如果有特殊需求(如:要匯出exce的報表)那這種才使用這種方式寫入excel
回覆中加入附件並不會使你增加積分,請使用主題方式發佈附件。

使用道具檢舉

Rank: 2Rank: 2

帖子
541
積分
212 點
潛水值
13707 米
頭香
發表於 2015-9-13 01:59 PM|只看該作者
如果發覺自己無法使用一些功能或出現問題,請按重新整理一次,並待所有網頁內容完全載入後5秒才進行操作。
列印與匯出成EXCEL檔案部分有做一些修正與加強,列印部分改成可以列出多頁。匯出EXCEL部分增加了會出後直接開啟EXCEL檔案的功能。
要改的地方蠻多的
1.在欄位的地方增加
  1. private PrintDocument pd = new PrintDocument();
  2. private string stringToPrint = "";
複製代碼
2.在Form_Load裏加上
  1. pd.PrintPage += new PrintPageEventHandler(printDocument_PrintPage);
複製代碼
3.把 或是後來再加入1筆資料 這一段改成下面這一段程式,直接增加70筆資料,列印時會分成2頁。
  1.             //或是後來再加入70筆資料
  2.             for (int i = 0; i < 70; i++)
  3.             {
  4.                 int idnum = 122551551;
  5.                 person.Add(new PersonModel
  6.                 {
  7.                     Name = "李維勳",
  8.                     ID = "T" + (idnum + i).ToString(),  //ID不同才會被視為不同一筆資料
  9.                     Birthday = "19750630",
  10.                     TEL = "02-23231122",
  11.                     CellPhone = "0938-777-777",
  12.                     Address = "台北市松山區信義路二段300號11樓之1",
  13.                     EMail = "waishin64@extenalmail.dodogogo.com.tw"
  14.                 });
  15.             }
複製代碼
4.在toExcelButton_Click裏面finally這一段改成
  1.                 //釋放掉一些資源的程式碼
  2.                 NAR(tmprng);
  3.                 NAR(first_sheet);
  4.                 NAR(workBook);
  5.                 xlApplication.Quit();
  6.                 NAR(xlApplication);
  7.                 GC.Collect();
  8.                 if (File.Exists(xlfilename))
  9.                 {
  10.                     StartTimerKillMessageBox(3);
  11.                     MessageBox.Show("匯出成功!!3秒後將會開啟檔案...", "MessageBox");
  12.                     System.Diagnostics.Process ps = new System.Diagnostics.Process();
  13.                     //開啟EXCEL檔案
  14.                     ps.StartInfo = new System.Diagnostics.ProcessStartInfo(xlfilename);
  15.                     //或是開啟EXCEL檔案所在的目錄
  16.                     //ps.StartInfo = new System.Diagnostics.ProcessStartInfo(fd.SelectedPath);
  17.                     ps.Start();
  18.                 }
複製代碼
5.把toPrinter_Click裡面所有程式碼改成
  1.             if (toExcelString == "") return;
  2.             string tmpstr = "";
  3.             string[] ss = System.Text.RegularExpressions.Regex.Split(toExcelString, "\r\n");
  4.             foreach (string s in ss)
  5.             {   //以下這段程式是將文字稍作排版
  6.                 if (s.Length < 5) continue;
  7.                 string[] sv = System.Text.RegularExpressions.Regex.Split(s, "\t");
  8.                 if (sv.Length == 7)
  9.                 {   
  10.                     //姓名是中文資料,要另外處理,所以又加了另一個擴充方法ToChtSubstring
  11.                     tmpstr += (ChtStr_Length(sv[0]) <= 12) ? sv[0] + new String(' ', 12 - ChtStr_Length(sv[0])) : sv[0].ToChtSubstring(0, 12);
  12.                     tmpstr += (sv[1].Length <= 11) ? sv[1] + new String(' ', 11 - ChtStr_Length(sv[1])) : sv[1].Substring(0, 11);
  13.                     tmpstr += (sv[2].Length <= 11) ? sv[2] + new String(' ', 11 - ChtStr_Length(sv[2])) : sv[2].Substring(0, 11);
  14.                     tmpstr += (sv[3].Length <= 16) ? sv[3] + new String(' ', 16 - ChtStr_Length(sv[3])) : sv[3].Substring(0, 16);
  15.                     tmpstr += (sv[4].Length <= 16) ? sv[4] + new String(' ', 16 - ChtStr_Length(sv[4])) : sv[4].Substring(0, 16);
  16.                     //地址也是中文資料,同樣另外處理
  17.                     tmpstr += (ChtStr_Length(sv[5]) <= 42) ? sv[5] + new String(' ', 42 - ChtStr_Length(sv[5])) : sv[5].ToChtSubstring(0, 42);
  18.                     tmpstr += (sv[6].Length <= 40) ? sv[6] + new String(' ', 40 - ChtStr_Length(sv[6])) : sv[6].Substring(0, 40);
  19.                     tmpstr += "\r\n";
  20.                 }
  21.             }
  22.             stringToPrint = tmpstr;
  23.             try
  24.             {
  25.                 //設定成橫印
  26.                 pd.DefaultPageSettings.Landscape = true;
  27.                 //列印輸出
  28.                 //叫出列印對話框
  29.                 PrintDialog pdialog = new PrintDialog();
  30.                 pdialog.Document = pd;
  31.                 if (pdialog.ShowDialog() == DialogResult.OK)
  32.                 {
  33.                     pd.Print();
  34.                 }
  35.             }
  36.             catch (Exception ex)
  37.             {
  38.                 throw new Exception("列印出錯:", ex);
  39.             }
複製代碼
6.增加一個PrintDocument處理PrintPage事件的函式
  1.         private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
  2.         {
  3.             //每頁字數
  4.             int charactersOnPage = 0;
  5.             //每頁的列數
  6.             int linesPerPage = 0;
  7.             //目前預設印表機可印範圍的高度
  8.             float h = pd.DefaultPageSettings.PrintableArea.Height - 40;
  9.             //目前預設印表機可印範圍的寬度(這裡將兩個參數減掉一些數據,是因為通常都不會滿版列印)
  10.             float w = pd.DefaultPageSettings.PrintableArea.Width - 80;
  11.             //如果是設定為橫印時,要將寬與高對調
  12.             if (pd.DefaultPageSettings.Landscape)
  13.             {
  14.                 float tmp = h;
  15.                 h = w;
  16.                 w = tmp;
  17.             }
  18.             //計算出每頁字數,每頁列數
  19.             e.Graphics.MeasureString(stringToPrint,
  20.                 new Font("標楷體", 11),
  21.                 new SizeF(w, h),
  22.                 StringFormat.GenericTypographic,
  23.                 out charactersOnPage,  //輸出給每頁字數的變數
  24.                 out linesPerPage);     //輸出給每頁列數的變數
  25.             //畫出列印頁面
  26.             e.Graphics.DrawString(stringToPrint,
  27.                 new Font("標楷體", 11),
  28.                 Brushes.Black,
  29.                 new RectangleF(20, 50, w, h), //這是跟邊界有關的4個參數
  30.                 StringFormat.GenericTypographic);

  31.             //取出每一頁字數的剩餘部分
  32.             stringToPrint = stringToPrint.Substring(charactersOnPage);
  33.             //一直到沒有頁面可以列印為止
  34.             e.HasMorePages = (stringToPrint.Length > 0);
  35.         }
複製代碼
7.在ExtensionUtility裏增加一個ToChtSubstring()的擴充方法
  1.         public static String ToChtSubstring(this String s, int starindex, int lenght)
  2.         {
  3.             byte[] linestr = System.Text.Encoding.Default.GetBytes(s);
  4.             return System.Text.Encoding.Default.GetString(linestr, starindex, lenght);
  5.         }
複製代碼
嫌麻煩的話可以直接下載整個專案檔案來參考看看喔
下載: 訪客無法瀏覽下載點,請先 註冊登入會員
...
瀏覽完整內容,請先 註冊登入會員
分享使你變得更實在,可以使其他人感到快樂,分享是我們的動力。今天就來分享你的資訊、圖片或檔案吧。

使用道具檢舉

您需要登錄後才可以回帖 登錄 | 註冊

Powered by Discuz!

© Comsenz Inc.

重要聲明:本討論區是以即時上載留言的方式運作,對所有留言的真實性、完整性及立場等,不負任何法律責任。而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。於有關情形下,用戶應尋求專業意見(如涉及醫療、法律或投資等問題)。 由於本討論區受到「即時上載留言」運作方式所規限,故不能完全監察所有留言,若讀者發現有留言出現問題,請聯絡我們。有權刪除任何留言及拒絕任何人士上載留言,同時亦有不刪除留言的權利。切勿上傳和撰寫 侵犯版權(未經授權)、粗言穢語、誹謗、渲染色情暴力或人身攻擊的言論,敬請自律。本網站保留一切法律權利。
回頂部