REPORTING WITH PRINTDOCUMENT IN .NET

Due to flexibility in creating reports with some tools in the .NET framework , using PrintDocument() class in creating reports is fading out. But sometimes you don’t have a choice but to use it. For instance creating reports without any predefined data source or generating reports where needed columns are determined at runtime.

In this post we will go through creating a report using the PrintDocument. Our datasoure will also come from a listview which contains a list of file types and their sizes from an indexed drive. When using the report document everything is drawn to the report interface, thus you draw a string, an image,a line. the difficulty in here also is, you yourself determine at runtime where your text, lines and images should be positioned

To start with, first drag a PrintPreviewDialog control on your form. The control is named “PrintPreview1”.

image

Then go to the code view and create  your procedure below.

Private Sub detaildisksreport_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
        Dim linesPerPage As Single = 0
        Dim yPos As Single = 0
        Static count As Integer = 0
        Dim x, y, c, i As Integer
        Dim leftMargin As Single = e.MarginBounds.Left
        Dim topMargin As Single = e.MarginBounds.Top

        ‘declaring fonts to use in your reports
        Dim backFont As New Font("Arial", 10, FontStyle.Italic)
        Dim HeaderFont As New Font("Arial", 20, FontStyle.Bold)
        Dim normfont As New Font("Times New Roman", 18, FontStyle.Regular)

        ‘ Calculate the number of lines per page.
        linesPerPage = e.MarginBounds.Height / normfont.GetHeight(e.Graphics)

        ‘x determines the horizontal positions whiles y determines the vertical position

        ‘ Drawing an image on top of the report
        Dim b As Rectangle
        Dim pic As New Rectangle(40, 5, pic1.Width + 40, pic1.Height + 40)
        e.Graphics.DrawImage(pic1.Image, pic)

        ‘drawing a line around the image
        b = New Rectangle(40, 5, pic1.Width + 40, pic1.Height + 40)
        e.Graphics.DrawRectangle(Pens.Black, b)

        linesPerPage = e.MarginBounds.Height / normfont.GetHeight(e.Graphics)
        linesPerPage = linesPerPage – 5

        ‘ Drawing our report titles
        x = 190
        y = pic1.Height + 70

        e.Graphics.DrawString("DETAIL DRIVE REPORT", HeaderFont, Brushes.Black, x, y)

        y += 40
        x = 25
        e.Graphics.DrawString(" FOLDERS ON DRIVE :  " & Me.cmbCat.SelectedItem.ToString.ToUpper, HeaderFont, Brushes.Black, x, y)
        y += 40
        x = 10
        e.Graphics.DrawString("REPORT GENERATED ON " & Now.ToLongDateString.ToUpper, HeaderFont, Brushes.Black, x, y)
        y += 10
        x = 5

        e.Graphics.DrawLine(Pens.Black, 5, y + 30, 820, y + 30)
        x = 10
        y += 60
        c = y

        e.Graphics.DrawString("FOLDER NAME", HeaderFont, Brushes.Blue, x, y)
        x += 260

        e.Graphics.DrawString("NUMBER OF FILES", HeaderFont, Brushes.Blue, x, y)
        x += 330

        e.Graphics.DrawString("FOLDER SIZE", HeaderFont, Brushes.Blue, x, y)

        e.Graphics.DrawLine(Pens.Black, 5, y + 30, 820, y + 30)

        x = 33
        y = c + 40

        i = 0
        ‘adding the content to the report
        For i = count To Me.LsvCDs.Items.Count – 1

            Dim len As Integer
            If LsvCDs.Items.Item(i).SubItems(0).Text.Length > 25 Then
                len = 25
            Else
                len = LsvCDs.Items.Item(i).SubItems(0).Text.Length
            End If

            e.Graphics.DrawImage(Me.SmallImages.Images(0), 15, y + 2)

            e.Graphics.DrawString(Me.LsvCDs.Items.Item(i).SubItems(0).Text.Substring(0, len), normfont, Brushes.Blue, x, y)
            x += 400
            e.Graphics.DrawString(Me.LsvCDs.Items.Item(i).SubItems(1).Text, normfont, Brushes.Blue, x, y)
            x += 220
            e.Graphics.DrawString(Me.LsvCDs.Items.Item(i).SubItems(2).Text, normfont, Brushes.Blue, x, y)

            ‘setting the y value to point to the next line
            ‘reseting the x value to the margin
            y += 30
            x = 33

            ‘checking to see if the current page is full
            If y + normfont.Height > e.PageSettings.PaperSize.Height Then
                count = i + 1
                e.HasMorePages = True
                Return

            End If
        Next

        count = 0
        e.HasMorePages = False
    End Sub

Also add the code below to a button click event and you are good to go.

   1: Dim pd As New PrintDocument()

   2: 'adding the print method created to the printdocument printpage event

   3: AddHandler pd.PrintPage, AddressOf disksreport_PrintPage

   4:  

   5: 'passing the print doucument to the PrintPreviewDialog

   6: PrintPreview1.Document = pd

   7: PrintPreview1.ShowDialog()

Below are sample interfaces, using printDocument to generate reports

image

image

Advertisements

TABLEMODEL AS DATASOURCE IN JASPER REPORTS

It is a common requirement in many J2SE (client,swing) applications to present data in a tabular way and also print this tabular format as a report.

Jasper reports provides implementation that makes the task of generating reports from tabular formats simple in Swing
applications. In this demonstrations, we will be using Jasper reports 3.6.1, Netbeans 6.1 and Ireport 3.6.1.

Let start by designing our report. In generating reports from tablemodels the report fields must match the column names of the tablemodel, but sometimes it becomes impractical to use the actual column names as report fields. Jasper Reports provides a way to generate reports from TableModels without having to map the actual table columns to the report fields. We can name our
report fields COLUMN_X, where x is the column index, starting with zero. Note “COLUMN” all characters should be capitals as “column” will give you error message at run time.

Also in case you have 3 columns in your table and you define a report field “COLUMN_4” , which is for column 5, null values will be displayed for each row in the report under that field. To prevent null values from displaying in a text field you can edit the expression for that field e.g. (($F{COLUMN_4}==null)? "":$F{COLUMN_4}.toString()), which means if the if the value of $F{COLUMN_4} is null ,display nothing else display the value. To do this, right click the text field and select “edit expression”, an expression editor will pop up for you to change the expression.

Below is a picture of our report at design time

image

After creating our report, we go to our application (using Netbeans as the IDE), we add a JTable and a JButton to our JFrame. We the create a method which accepts  the table model to create the report, tbProducts is the name of the Jtable. Check https://gilbertadjin.wordpress.com/2009/05/05/populating-a-jtable-with-a-collection-list/ to see how to populate a list of javabean object to a Jtable

private void generateReports(String name, Map param) {
        try {

      String source = "C:/sabonay/jasperreports/" + name + ".jrxml";
            if (new File(source).exists() == false) {
      xputils.showMessage("Please go to setting and Choose report Source");
                return;
            }

JasperReport jasperReport = JasperCompileManager.compileReport(source);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, param, new JRTableModelDataSource(tbProducts.getModel()));

            JasperViewer.viewReport(jasperPrint, false);

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("reports Error  " + e.toString());

        }

Cheers !!!

LOAD IMAGES DYNAMICALLY INTO JASPER REPORTS

If you want to insert images from the file system (e.g. C:\images folder) into jasper reports at runtime, for example changing a logo depending on user selection or simply allowing the user to browse for his or her image to be displayed  in the report then here is a simple process of doing that.

Let start with the report design using ireport. In this instance the picture will be passed to the report as a parameter.

So let’s create a parameter in our report and call it “photo”

image

As shown in the picture above, the data type of our parameter should be “java.lang.Object”

After this, drag the image , from the tool bar, on to your report.Right click on the image and choose “Properties” from the menu

image

Under the image tab of the dialog box, make sure you select “java.awt.image” for the Image Expression Class. Once this is done, you are done with the report design

Lets go to netbeans , do some coding and connect our designed report to a java application.

First we need to declare a variable of type image,

Image photo;

Also we create a method , which on click of a button, loads a picture from the file system and initializes the “photo: variable.

JFileChooser fc = new JFileChooser();

private void getPicture() {

fc.setFileFilter(new FileNameExtensionFilter("Images", "jpg", "gif", "bmp"));

if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {

fc.setCurrentDirectory(fc.getCurrentDirectory());

ImageIcon icon = new ImageIcon(fc.getSelectedFile().getAbsolutePath());

icon = new ImageIcon(icon.getImage().getScaledInstance(350, 350, Image.SCALE_DEFAULT));

photo = icon.getImage();

}

After getting our picture, create an instance of the Map class and pass our “variable” as a parameter.

Map<String, Object> param = new HashMap<String, Object>();

param.put("photo", photo); //the “photo” should be the same name as the parameter name in our report

We then create a method that passes our created parameter to the report and we are done. below is the method that does the job.

private void generateReports(String name, Map param) {

try {

String source = "C:/sabonay/jasperreports/" + name + ".jrxml";

if (new File(source).exists() == false) {

xputils.showMessage("Please  report Source does not exist");

return;

}

JasperReport jasperReport = JasperCompileManager.compileReport(source);

JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, param, new JREmptyDataSource());

JasperViewer.viewReport(jasperPrint, false);

//the false parameter makes sure the application does not close on closing the report

} catch (Exception e) {

System.out.println("reports Error " + e.toString());

}}

Make sure to reference the necessary jasper jar files in your application