DataGridView' da Bulunan Satırları Yazdırmak

12.08.2012 Hikmet Okumuş 5310 22 C#


Merhaba Arkadaşlar, Datagridview üzerinde bulunan satırların önizleme ve yazıcı çıktısı olarak nasıl alınabileceği ile ilgili bir işlemi aşağıdaki satırları takip ederek yapabilirsiniz.
1. İşlemimiz grid' in dolmasından sonra oluşacağı için kullanılan database türünün bir önemi bulunmamaktadır. Biz sql olarak devam edelim. Sql' den verilerilerimizi çektik ve datagridview' ın içerisine doldurduk.
2. Global olarak aşağıda bulunan değişkenleri tanımlamamız gerekmektedir.
        StringFormat strFormat;
        ArrayList arrColumnLefts = new ArrayList();
        ArrayList arrColumnWidths = new ArrayList();
        int iCellHeight = 0;
        int iTotalWidth = 0;
        int iRow = 0;
        bool bFirstPage = false;
        bool bNewPage = false;
        int iHeaderHeight = 0;
3. Formumuza bir tane printDocument nesnesi ekliyoruz. Öncelikle printDocument1_PrintPage eventına aşağıda bulunan kodu yazıyoruz.
            try
            {
                int iLeftMargin = e.MarginBounds.Left;
                int iTopMargin = e.MarginBounds.Top;
                bool bMorePagesToPrint = false;
                int iTmpWidth = 0;
                bFirstPage = true;
                
                if (bFirstPage)
                {
                    foreach (DataGridViewColumn GridCol in dataGridView1.Columns)
                    {
                        iTmpWidth = (int)(Math.Floor((double)((double)GridCol.Width /
                                       (double)iTotalWidth * (double)iTotalWidth *
                                       ((double)e.MarginBounds.Width / (double)iTotalWidth))));

                        iHeaderHeight = (int)(e.Graphics.MeasureString(GridCol.HeaderText,
                                    GridCol.InheritedStyle.Font, iTmpWidth).Height) + 11;

                        
                        arrColumnLefts.Add(iLeftMargin);
                        arrColumnWidths.Add(iTmpWidth);
                        iLeftMargin += iTmpWidth;
                    }
                }
                
                while (iRow <= dataGridView1.Rows.Count - 1)
                {
                    DataGridViewRow GridRow = dataGridView1.Rows[iRow];
                
                    iCellHeight = GridRow.Height + 5;
                    int iCount = 0;
                
                    if (iTopMargin + iCellHeight >= e.MarginBounds.Height + e.MarginBounds.Top)
                    {
                        bNewPage = true;
                        bFirstPage = false;
                        bMorePagesToPrint = true;
                        break;
                    }
                    else
                    {
                        if (bNewPage)
                        {
                            
                            e.Graphics.DrawString("Çıktı Başlığı", new Font(dataGridView1.Font, FontStyle.Bold),
                                    Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top -
                                    e.Graphics.MeasureString("Çıktı Başlığı", new Font(dataGridView1.Font,
                                    FontStyle.Bold), e.MarginBounds.Width).Height - 13);

                            String strDate = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString();
                            
                            e.Graphics.DrawString(strDate, new Font(dataGridView1.Font, FontStyle.Bold),
                                    Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width -
                                    e.Graphics.MeasureString(strDate, new Font(dataGridView1.Font,
                                    FontStyle.Bold), e.MarginBounds.Width).Width), e.MarginBounds.Top -
                                    e.Graphics.MeasureString("Çıktı Başlığı", new Font(new Font(dataGridView1.Font,
                                    FontStyle.Bold), FontStyle.Bold), e.MarginBounds.Width).Height - 13);

                            
                            iTopMargin = e.MarginBounds.Top;
                            foreach (DataGridViewColumn GridCol in dataGridView1.Columns)
                            {
                                e.Graphics.FillRectangle(new SolidBrush(Color.LightGray),
                                    new Rectangle((int)arrColumnLefts[iCount], iTopMargin,
                                    (int)arrColumnWidths[iCount], iHeaderHeight));

                                e.Graphics.DrawRectangle(Pens.Black,
                                    new Rectangle((int)arrColumnLefts[iCount], iTopMargin,
                                    (int)arrColumnWidths[iCount], iHeaderHeight));

                                e.Graphics.DrawString(GridCol.HeaderText, GridCol.InheritedStyle.Font,
                                    new SolidBrush(GridCol.InheritedStyle.ForeColor),
                                    new RectangleF((int)arrColumnLefts[iCount], iTopMargin,
                                    (int)arrColumnWidths[iCount], iHeaderHeight), strFormat);
                                iCount++;
                            }
                            bNewPage = false;
                            iTopMargin += iHeaderHeight;
                        }
                        iCount = 0;
                                   
                        foreach (DataGridViewCell Cel in GridRow.Cells)
                        {
                            if (Cel.Value != null)
                            {
                                e.Graphics.DrawString(Cel.Value.ToString(), Cel.InheritedStyle.Font,
                                            new SolidBrush(Cel.InheritedStyle.ForeColor),
                                            new RectangleF((int)arrColumnLefts[iCount], (float)iTopMargin,
                                            (int)arrColumnWidths[iCount], (float)iCellHeight), strFormat);
                            }
                        
                            e.Graphics.DrawRectangle(Pens.Black, new Rectangle((int)arrColumnLefts[iCount],
                                    iTopMargin, (int)arrColumnWidths[iCount], iCellHeight));

                            iCount++;
                        }
                    }
                    iRow++;
                    iTopMargin += iCellHeight;
                }

                
                if (bMorePagesToPrint)
                    e.HasMorePages = true;
                else
                    e.HasMorePages = false;
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
4. Aynı şekilde printDocument1_BeginPrint eventına aşağıda bulunan kodu yazıyoruz.
            try
            {
                strFormat = new StringFormat();
                strFormat.Alignment = StringAlignment.Near;
                strFormat.LineAlignment = StringAlignment.Center;
                strFormat.Trimming = StringTrimming.EllipsisCharacter;

                arrColumnLefts.Clear();
                arrColumnWidths.Clear();
                iCellHeight = 0;
                iRow = 0;
                bFirstPage = true;
                bNewPage = true;

                iTotalWidth = 0;
                foreach (DataGridViewColumn dgvGridCol in dataGridView1.Columns)
                {
                    iTotalWidth += dgvGridCol.Width;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
5. Gelelim önizleme ile datagridview üzerinde bulunan satırların görüntülenmesine. Formumuza bir button ekliyoruz ve Click eventına aşağıda bulunan kodu ekliyoruz.
            PrintPreviewDialog onizleme = new PrintPreviewDialog();
            onizleme.Document = printDocument1;
            onizleme.ShowDialog();
6. Önizleme görüntüsünü bu şekilde elde etmiş olduk. Artık önizlemenin üzerinde bulunan menüden yazdır işlemini yapabilirsiniz. Fakat sizler direk yazıcıya çıktı göndermek isterseniz aşağıdaki kod ile bunu yapabilirsiniz.
            PrintDialog yazdir = new PrintDialog();
            yazdir.Document = printDocument1;
            yazdir.UseEXDialog = true;
            if (yazdir.ShowDialog() == DialogResult.OK)
            {
                printDocument1.Print();
            }
Bu işlemler sonucunda datagridview üzerinde bulunan kayıtların çıktısını alabilirsiniz. Dilerim faydalı bir anlatım olmuştur.

Başarılar dilerim.


Kullanıcı Yorumları


hikmet okumuş makale yorum
MURAT
07.05.2015 03:45:26
ellerine sağlık kardes bi sorum olacak biz bu baskı ön izlemeyi nasıl büyütebilirim acılışta cok küçük
hikmet okumuş makale yorum
Hikmet Okumuş
07.05.2015 13:58:34
Merhaba Murat, PrintPreviewDialog onizleme = new PrintPreviewDialog(); onizleme.Document = printDocument1; ((Form)onizleme).WindowState = FormWindowState.Maximized; // Tam ekran olması için onizleme.PrintPreviewControl.Zoom = 1.0; //Sayfanın %100 boyutunda olması için onizleme.ShowDialog(); Yukarıdaki kod işini görecektir. Fakat dikkat edersen onizleme objesini "Form" nesnesine cast ederek WindowState özelliğine eriştim. Bunun sebebi şudur; PrintPreviewDialog nesnesindeyken "Go To Definition" dersen, nesnenin "Form" nesnesinden türetildiğini ve nesnenin WindowState property' sine sahip olduğunu göreceksin. Fakat property "[EditorBrowsable(EditorBrowsableState.Never)]" ile gizlendiği için doğrudan erişilemez ve özelliği kullanabilmemiz için cast işlemi yapmamız gerekmektedir. Başarılar dilerim.
hikmet okumuş makale yorum
mustafa ersoy
10.05.2015 20:36:09
merhaba. ben bu şekilde yaptıgım zaman "onizleme.ShowDialog();" kısmında Yüklü Yazıcı Yok hatası alıyorum yardımcı olur musunuz ?
hikmet okumuş makale yorum
Hikmet Okumuş
11.05.2015 00:21:57
Merhaba Mustafa Ersoy, PrintPreviewDialog ile show işleminden önce sistemde tanımlı yazıcı olup olmadığını kontrol edebilirsin. Eğer tanımlı yazıcı varsa Showdialog ile ekran açarsın. Yüklü yazıcıları aşağıdaki şekilde elde edebilirsin. System.Drawing.Printing.PrinterSettings.InstalledPrinters
hikmet okumuş makale yorum
Ozge TANIS
30.10.2015 04:26:23
Merhaba Hikmet Bey, Öncelikle kodu bu kadar anlaşılır ve uygulaması kolay yayımladığınız için teşekkür ederim. Kodu basit bir sipariş programında kullandım çıktı 80mm lik kağıda olacak, datagridview u bitmap şeklinde yazdırdığımda sayfaya tam uyduruyorum ancak görünenin dışında ki satırları yazmıyor, sizin kodunuzu kullandığımda ise istediğim iki sütun satırların hepsi yazıyor ama sütunların genişliği oldukça daralıyor, genişlik değerini uyarlayabileceğimiz yada kullandığım datagridviewden sütun genişlik değerini almasını sağlayacak bir öneriniz olabilir mi? Saygılarımla
hikmet okumuş makale yorum
Hikmet Okumuş
30.10.2015 16:45:47
Merhaba Ozge TANIS, "BeginPrint" event' ı içerisinde yazdırılacak gridin toplam sütun genişliği hesaplanmaktadır. Hesaplanan toplam kolon genişlikleri "iTotalWidth" isimli değişkende tutulmaktadır. Sonrasında "PrintPage" event' ında toplam kolon sayısına göre bir genişlik ortalaması alınıyor ve değer "iTmpWidth" değişkeninde tutuluyor. Yani ilgili kolon genişliği artık bu değer oluyor. Tüm kolon genişlikleri de "arrColumnWidths" isimli dizide tutulmaktadır. Sonrasında her bir satır ve sutun oluşurken bu dizideki değere göre genişlikleri belirlenmektedir. Yazdırma alanında bulunan kolon genişliklerini bu şekilde yönetebilirsin.
hikmet okumuş makale yorum
Ozge TANIS
01.11.2015 23:58:06
Hikmet Bey, Cevabınız için teşekkür ederim. Biraz uğraştıktan sonra sorunumun sütun genişliklerinde değil kağıt kenar boşluklarında olduğunu anladım, kağıt boyutu ne olursa olsun sağ ve soldan bırakılan kenar boşlukları sütun genişliklerini etkiledi, dediğiniz gibi sütun boyutları da formda belirttiğimiz orana göre genişleyip darabiliyor, bende aşağıdaki kodları printdocument in Begin_Print eventine ekleyerek sağ sol boşlukları sıfırladım ve çıktı tam istediğim gibi oldu, vermiş olduğunuz kodlar sayesinde de hücre içeriği gerekirse 2 satır olarak satırıma sığdı. Tekrar teşekkürler. printDocument1.OriginAtMargins = true; printDocument1.DefaultPageSettings.Margins.Left = 0; printDocument1.DefaultPageSettings.Margins.Right = 0; printDocument1.DefaultPageSettings.Margins.Top = 40; printDocument1.DefaultPageSettings.Margins.Bottom = 0;
hikmet okumuş makale yorum
Hikmet Okumuş
02.11.2015 00:03:46
Özge Hanım, Sorununuzu çözmüş olmanıza sevindim. İlginiz için ben teşekkür ederim.
hikmet okumuş makale yorum
Ömer Faruk Dönmez
02.03.2016 00:11:11
Hücre içeriğini gerektiği zaman 3 veya 4 satır olarak ayarlayabilirmiyiz.
hikmet okumuş makale yorum
fatih demir
06.01.2017 12:16:14
Emeğinize sağlık işime yaradı tşkler
hikmet okumuş makale yorum
Deniz YAZAR
07.03.2017 14:24:58
Hocam Merhaba, Yaptığın uygulamada datagridview in sutunlarından bir tanesini gizlemek istiyorum, hangi satırda oynama yapmam gerekli? Birde yazdırdığım her bir belge üzerine sayfa numarasını yazdırmak istiyorum. Sayfa [1 / 10] gibi... bunu nasıl sağlayabilirim, yardımcı olursan çok sevinirim.
hikmet okumuş makale yorum
Hikmet OKUMUŞ
08.03.2017 02:04:31
Merhaba Deniz YAZAR, Öncelikle sayfa numarasını yazdırma soruna cevap vereyim. String olarak "Çıktı Başlığı" yazan bir bölüm bulunmaktadır. (1. sıradaki kod) Kendine global bir değişken tanımlayarak buraya string.format ile istediğin şekilde sayfa numarasını yazdırabilirsin. pageCount yukarıdaki örnekte olmayan yeni tanımladığım global bir int türünde değişken, sayfa sayısını bu değişken tutmaktadır. e.Graphics.DrawString("Çıktı Başlığı - Sayfa " + pageCount, new Font(dataGridView1.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString("Çıktı Başlığı", new Font(dataGridView1.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13); Kolonları gizlemek bu örnek kod üzerinden gideceksen biraz zahmetli olabilir. Yukarıdaki kod içinde yapmak istersen şöyle bir tavsiyede bulunabilirim. Gizlemek istediğin kolon ya da kolonları bir koleksiyon içerisinde tutarsın. Ardından aşağıdaki gibi kolonları dikkate almazsın. if (hideColumns.Any(x => x.Equals(GridCol.Name))) continue; Sayfa üzerinde kolonların genişliklerini dinamik ayarladığı için, böyle bir işlem sonrasında kolon ayarlamasını da senin yeniden hesaplatman gerekecektir. 3 yerde döngü ile kolonları dolaşıyor. Bu şekilde deneyebilirsin.
hikmet okumuş makale yorum
Mustafa AKBAL
06.04.2017 23:41:37
Teşekkürler. Çok iyi oldu bu kodlar. Ama arrayList ilk eklendiğinde hata veriyor onun için using System.Collections; isim uzayını eklemeyi unutmayın.
hikmet okumuş makale yorum
Doğancan ULUTş
10.04.2017 12:43:14
Hocam Öncelikle merhaba; ben kodu yazdım dediğiniz gibi ancak global olarak tanımladığımız kısımda array list de hata verdi bide o kısımda en altta int iHeaderHeight = 0 da 0 hata veriyor çok baktım ama sebebini bulamadım nedir sorun acaba ?
hikmet okumuş makale yorum
Yiğit Çevik
22.04.2017 15:26:53
Merhabalar hocam, dataGridView'in çıktı aldıktan sonra nasıl kenarlığı kaldıracağız mümkün müdür acaba? Bu arada yazı için teşekkürler çok işime yaradı :) Allah razı olsun
hikmet okumuş makale yorum
Hikmet Okumuş
23.04.2017 00:53:02
Merhaba Yiğit Çevik, foreach (DataGridViewCell Cel in GridRow.Cells) ile başlayan döngünün içerisinde e.Graphics.DrawRectangle(Pens.Black, new Rectangle((int)arrColumnLefts[iCount], iTopMargin, (int)arrColumnWidths[iCount], iCellHeight)); satırında "Pens.Black" kısmını "Pens.Transparent" şeklinde değiştirirsen border gözükmeyecektir. Başlık kısmını da aynı şekilde yok edebilirsin. Başlıkta hem border hem de background olarak 2 yerde geçer. Aynı şekilde Transparent olarak o kısımları da set edebilirsin.
hikmet okumuş makale yorum
Yunus Emre
17.05.2017 13:51:53
Hikmet Bey merhabalar. Anlatımınız ve paylaşımınız için çok teşekkür ederim. Emeğinize sağlık. Projeme gösterdiğiniz şekilde ekleyerek yaptım hiç hata almıyorum ama çıktı da alamıyorum. Yani sayfa boş geliyor. DatagridView de kayıtlarım mevcut ama yine de boş geliyor. Gözden kaçırdığım bir püf noktası var mı acaba? Yani kodlarda bizim değiştirmemiz gereken bir yer varmı?
hikmet okumuş makale yorum
Hikmet Okumuş
17.05.2017 14:13:30
Merhaba Yunus Emre, Öncelikle Datagrid kontrolünün DataSource özelliğine değerin set edilmiş olması gerekmektedir. Kodda aşağıdaki satıra breakpoint ekleyerek debug edebilir misin ? "while (iRow <= dataGridView1.Rows.Count - 1) " Burada grid içerisinde satır varsa sana çıktı görselini çizecektir. Tekrar sorun yaşarsan kod bloğunu bana iletişim kısmından gönder, yardımcı olmaya çalışırım.
hikmet okumuş makale yorum
Yunus Emre
17.05.2017 14:35:49
Maalesef sonuç alamadım Hikmet bey. Projemin kodlarını iletişim kısmından yolladım. Yardımcı olabilirseniz çok sevinirim. Geri dönüş için teşekkür ederim.
hikmet okumuş makale yorum
Hikmet Okumuş
17.05.2017 15:10:53
Merhaba Yunus Emre, Muhtemelen boş gelmesinin nedeni "printDocument" kontrolünün BeginPrint ve PrintPage eventlarının boş olmasından kaynaklanıyor. Makalede 3. ve 4. aşamada printDocument nesnesine hangi eventları ekleyeceğini ve içerisine hangi kodları ekleyeceğin yazıyor. Kontrolü seç properties panelinden event kısmına geç ve orada ilgili eventların seçili / tanımlı olduklarından emin ol. Bunu yaptığında ekrana çıktıyı getirebilirsin.
hikmet okumuş makale yorum
Yunus Emre
17.05.2017 15:28:01
Şimdi oldu işte. Çok çok teşekkür ederim Hikmet bey. Allah razı olsun.
hikmet okumuş makale yorum
Hikmet Okumuş
17.05.2017 15:39:06
Rica ederim.


Yorum