C#: atestat și pregătire ONTI

C#: rapoarte tipărite și paginare cu PrintDocument

Pregătește un raport C# pentru previzualizare și tipărire. Folosește marginile paginii, continuarea pe pagina următoare și resetarea stării la fiecare rulare.

Un raport nu este o captură a ferestrei. Hârtia are alte dimensiuni, margini și reguli de paginare. PrintDocument cere aplicației să deseneze fiecare pagină în PrintPage. Păstrăm indexul următorului rând și îl resetăm în BeginPrint, astfel încât o a doua previzualizare să înceapă de la primul element.

Cum lucrezi cu exemplul

Exemplul complet se compilează ca Windows Forms App pe .NET Framework 4.8, cu C# 7.3. Deschide Lesson.csproj din arhivă în Visual Studio pe Windows. Rulează scenariile descrise mai jos; verificarea compilării nu înlocuiește testarea ferestrei și a dispozitivelor folosite.

Descarcă sursele și instrucțiunile.

Ideea și pașii de implementare

MarginBounds descrie zona imprimabilă aleasă pentru raport. Fiecare rând consumă o înălțime calculată din font. Când următorul rând nu încape, HasMorePages devine true. Sistemul va cere o pagină nouă, iar indexul deja avansat permite continuarea fără repetare.

PrintPreviewDialog afișează rezultatul folosind același PrintDocument. Exemplul cere un subsistem de tipărire Windows disponibil; dacă nu există o imprimantă configurată, raportăm situația. Previzualizarea nu dovedește că o imprimantă fizică a produs corect hârtia.

Exemplu și rezultat așteptat

Raportul conține 120 de rânduri numerotate. În previzualizare, primul rând este 1, ultimul este 120 și niciun rând nu se repetă la schimbarea paginii. Închizi previzualizarea și o deschizi din nou: începe tot de la 1, datorită resetării în BeginPrint.

Schemă pentru lecția 26: BeginPrint: index 0; Rânduri în MarginBounds; Pagina plină; HasMorePages → continuare.BeginPrint: index 0 → Rânduri în MarginBounds → Pagina plină → HasMorePages → continuare.Mărește schema ↗

Codul complet

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new LessonForm());
    }
}

class LessonForm : Form
{
readonly System.Drawing.Printing.PrintDocument document=new System.Drawing.Printing.PrintDocument();
    readonly string[] rows=Enumerable.Range(1,120).Select(i=>"Rand " + i).ToArray();
    int next;
    public LessonForm() {
        Text="Raport";ClientSize=new Size(360,140);
        var preview=new Button {Left=20,Top=25,Width=240,Text="Previzualizare raport"};
        document.BeginPrint += (s,e) => {next=0;};
        document.PrintPage += (s,e) => {
            float y=e.MarginBounds.Top,step=Font.GetHeight(e.Graphics)+6;
            while(next<rows.Length && y+step<=e.MarginBounds.Bottom) {
                e.Graphics.DrawString(rows[next++],Font,Brushes.Black,e.MarginBounds.Left,y);y+=step;
            }
            e.HasMorePages=next<rows.Length;
        };
        preview.Click += (s,e) => {
            try {using(var dialog=new PrintPreviewDialog {Document=document,Width=900,Height=650})dialog.ShowDialog(this);}
            catch(System.Drawing.Printing.InvalidPrinterException) {MessageBox.Show(this,"Configureaza o imprimanta Windows.");}
        };
        Controls.Add(preview);
    }
    protected override void Dispose(bool disposing) {if(disposing)document.Dispose();base.Dispose(disposing);}
}

Greșeli și limite

Nu folosi coordonatele controlului de pe ecran drept coordonate de pagină. Nu uita să incrementezi indexul: ai putea cere pagini la nesfârșit. Nu elibera Graphics primit în eveniment. Fonturile sau documentele create și deținute de formular trebuie eliberate la închidere.

Exersează

Testează zero, un rând și 120 de rânduri. Pentru fiecare, verifică primul și ultimul număr și numărul total de rânduri vizibile. Schimbă orientarea paginii și confirmă că limita verticală este recalculată din MarginBounds. Adaugă un antet repetat pe fiecare pagină fără a-l număra ca rând de date.

Continuă parcursul

Parcursul complet de 50 de lecții

Bazele C#

Lecția precedentă: C#: grafice cu Chart și agregarea datelor

Lecția următoare: C#: resurse localizate și texte fără concatenări fragile.

Referință: documentația Microsoft.

Întrebări frecvente

De ce resetarea este în BeginPrint?

Evenimentul începe o nouă operație de tipărire sau previzualizare, deci raportul trebuie reluat de la început.

Cum cer o pagină suplimentară?

Setezi HasMorePages la true cât timp există date neafișate.

Previzualizarea dovedește tipărirea fizică?

Nu. Dovedește randarea raportului în previzualizare; imprimanta reală se verifică separat.

Un pas mai departe

Autentifică-te pentru a păstra progresul în cont.

Exersează cu o problemă →