DataGridView' da Bulunan Satırları Yazdırmak

12.08.2012 Hikmet Okumuş 6401 34 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.
hikmet okumuş makale yorum
Salih Gündoğdu
02.07.2017 20:52:13
Merhan kodlar için teşekkür ederim. Sayfa yapısı dikey olunca satırlar sığmıyor. Sayfa yapısını nasıl yatay olarak ayarlayabilirim. Birde benim formumda 2 Adet datagridview var ikisinide alt alta nasıl yazdırırım
hikmet okumuş makale yorum
Hikmet Okumuş
02.07.2017 23:51:22
Merhaba Salih Gündoğdu, 1. sorunu google da doğrudan aratabilir ve bununla ilgili bir çok sonuç bulabilirsin. Bu senin çok fazla arge yapmanı gerektirecek bir konu değil. Türkçe bile bir çok cevap bulabilirsin. Önce araştır, bulamazsan yardımcı olurum. 2. sorunda ise tek bir belgede yazdırmak için, örnekte dataGridView1 nesnesi kullanılmış ve bu nesnenin Rows, Columns koleksiyonlarında işlemler yapılmıştır. Tek bir belge için bu yapıyı 2 grid içinde kapsayacak şekilde ayarlaman gerekiyor. Yani kodda değişiklik yapman gerekecektir.
hikmet okumuş makale yorum
taner soysüren
05.07.2017 15:05:38
Merhaba Hikmet hocam Elinize saglik. Cok guzel bir proje paylasmissiniz. Benim takildigim bir nokta oldu. Yardimci olursaniz sevinirim. C# da yeniyim. Eger basit gelirse yanlis anlamayin. Yaziciya gonderirken sag ust tarafta tarih yaziyor. Ben bu tarihin altina degerini texboxtan alan bir tarih daha eklemek istiyorum. Boyle birsey mumkunmu acaba?
hikmet okumuş makale yorum
Hikmet Okumuş
06.07.2017 01:10:56
Merhaba Taner Soysüren, Evet yapabilirsin. "String strDate" ile başlayan kısmın hemen altında "e.Graphics.DrawString" ile ekrana tarihi basan bir kod bulunmaktadır. Bu kodu kopyala ve altına yapıştır, strDate alanını textbox tan alacak şekilde revize et. Sonra üst üste çakışmaması için location için Height bilgisini düzenle. Bu şekilde istediğin gibi bir işlemi yapabilirsin.
hikmet okumuş makale yorum
taner soysüren
06.07.2017 23:51:04
cok tesekkur ederim hikmet hocam. elinize bilginize saglik. basarilarin devamini dilerim.
hikmet okumuş makale yorum
Özkan
10.08.2017 12:17:53
Hocam paylaşımınız için teşekkür ederim çok işime yaradı.. Ama benim bir sorum olacak yazdır dediğimiz de gridwiewdeki bütün kolanları yazdırıyor ben sadece belirli kolanları yazdırmak istiyorum çıktısını almak istiyorum bunu yapmak mümkünmü
hikmet okumuş makale yorum
Hikmet Okumuş
11.08.2017 01:49:10
Merhaba Özkan, Yukarıda benzer bir soru daha önce sorulmuştu. Tavsiye bir yöntem önermiştim. İncelersen sana yapmak istediğin çalışma için fikir verebilir.
hikmet okumuş makale yorum
veysel gül
06.09.2017 12:34:35
Hikmet bey merhaba.Ben datagridview de click yaptığım tek satırın çıktısını almak istiyorum.Hepsini istemiyorum.Bunu nasıl yapabiliriz peki?Yardımcı olursanız çok sevinirim..
hikmet okumuş makale yorum
Hikmet Okumuş
07.09.2017 01:41:54
Merhaba Veysel Gül, Kodu aşağıdaki gibi revize edersen ve print preview işlemini grid' in doubleclick eventlarından birisine atarsan tek satıra ait bir çıktı elde edebilirsin. //while (iRow <= dataGridView1.Rows.Count - 1) while(iRow <= dataGridView1.SelectedRows.Count -1) { //DataGridViewRow GridRow = dataGridView1.Rows[iRow]; DataGridViewRow GridRow = dataGridView1.SelectedRows[iRow];
hikmet okumuş makale yorum
Şeyma Nurcan Doruk
22.09.2017 17:22:01
Merhaba; iTmpWidth = (int)(Math.Floor((double)((double)GridCol.Width / (double)iTotalWidth * (double)iTotalWidth * ((double)e.MarginBounds.Width / (double)iTotalWidth)))); projede başlangıçta çalışıyodu daha sonra double tanımlamalarını silik gösterip önizleme dediğimde tablo gelmedi sorun nedir?
hikmet okumuş makale yorum
taner soysüren
07.10.2017 02:59:44
Hocam tekrar merhaba. Bir sorum daha olacakti. Datagridviewi istedigimiz locationda nasil yazdiririz? mesela (0,80) gibi koordinattan baslatip yazdirmak istiyorum. Su andaki hali ortada yazdiriyor. Kagidin sol tarafina sifirlayip 80 ninci satirdan itibaren bastirmak istiyorum. Mumkunmu boyle birsey?
hikmet okumuş makale yorum
Ahmet Turan
17.10.2017 14:17:44
Merhaba Hikmet bey, Öncellikle sunduğunuz doküman için teşekkürler. Sorunum ise ön izleme ekranında bulunan yazdır alanının click olayına erişmek istiyorum. Yapmak istediğim yazdır kısmına bastığımda Windows yazıcı seçme ekranı ile yazıcıyı seçip öyle yazdırmak. Şimdiden teşekkürler.


Yorum