0
\$\begingroup\$

I have 2 DGV's one containing bills info & another containing credit notes info. When at least one item from both the DGV's are selected then it should generate a pdf (result1) taking data from both the DGV's & some standard header, footer & letter format text using some info.

scenario 1

result1

And when only billsDGV data is selected then it should be like below

scenario2

result2

Here is what I've done(button click event):

if (creditNotesDGV.SelectedRows.Count > 0)
{
    if (creditNotesDGV.SelectedRows.Count > 3)
    {
        MetroMessageBox.Show(this,"Please select 3 or less Credit/Debit notes","Selection Error",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
        return;
    }
    
    if (billsDGV.SelectedRows.Count > 0 && billsDGV.SelectedRows.Count < 9)
    {
        total = billsDGV.SelectedRows.OfType<DataGridViewRow>()
.Sum(t => Convert.ToDecimal(t.Cells[2].Value));
        
        _total = creditNotesDGV.SelectedRows.OfType<DataGridViewRow>()
.Sum(t => Convert.ToDecimal(t.Cells[2].Value));
        
        amt=total-_total;
        
        if (amt < 0) {
MetroMessageBox.Show(this,"Sum of CN/DN value is higher than sum of Invoice value!","Selection Error",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
return;
        }
        
        Gen1stTable();
        
        Gen2ndTable(pdoc);
        
        GenLastPart();

        pdoc.Close();
        
        Process.Start(@"F:\test.pdf");
        
    }
    
    
    else{
        MetroMessageBox.Show(this,"Please select minimum 1 item and/or maximum 8 items","Selection Error",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
    }

}


else
{
    if
        (billsDGV.SelectedRows.Count > 0 && billsDGV.SelectedRows.Count < 16)
    {
        
        Gen1stTable();
        
        GenLastPart();
        
        pdoc.Close();
        
        Process.Start(@"F:\test.pdf");
        
    }
    
    else{
        MetroMessageBox.Show(this,"Please select minimum 1 item and/or maximum 15 items","Selection Error",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
    }
}

Using the helper methods :

    decimal total, _total, amt;
    PdfWriter pwriter;
    iTextSharp.text.Document pdoc;
    iTextSharp.text.Font myfont=FontFactory.GetFont(iTextSharp.text.Font.FontFamily.TIMES_ROMAN.ToString(),20,iTextSharp.text.Font.BOLD, iTextSharp.text.BaseColor.BLUE);
    iTextSharp.text.Font _myfont=FontFactory.GetFont(iTextSharp.text.Font.FontFamily.TIMES_ROMAN.ToString(),14,iTextSharp.text.Font.BOLD, iTextSharp.text.BaseColor.BLUE);
    iTextSharp.text.Font myfont2=FontFactory.GetFont(iTextSharp.text.Font.FontFamily.TIMES_ROMAN.ToString(),11,iTextSharp.text.Font.NORMAL, iTextSharp.text.BaseColor.RED);
    iTextSharp.text.Font myfont3=FontFactory.GetFont(iTextSharp.text.Font.FontFamily.TIMES_ROMAN.ToString(),9,iTextSharp.text.Font.NORMAL, iTextSharp.text.BaseColor.BLACK);
    iTextSharp.text.Font myfont4=FontFactory.GetFont(iTextSharp.text.Font.FontFamily.TIMES_ROMAN.ToString(),12,iTextSharp.text.Font.NORMAL, iTextSharp.text.BaseColor.BLACK);

private iTextSharp.text.Font blankFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 9, iTextSharp.text.Font.BOLD | iTextSharp.text.Font.UNDERLINE, BaseColor.WHITE);
    private iTextSharp.text.Font headerFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 9, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
    private iTextSharp.text.Font standardFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 9, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
    private iTextSharp.text.Font totalfont=new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 12f, iTextSharp.text.Font.BOLD);

//Generates the header portion & the first table taking data from billsDGV
public iTextSharp.text.Document Gen1stTable()
    {
        total = billsDGV.SelectedRows.OfType<DataGridViewRow>()
            .Sum(t => Convert.ToDecimal(t.Cells[2].Value));
        
        _total = creditNotesDGV.SelectedRows.OfType<DataGridViewRow>()
            .Sum(t => Convert.ToDecimal(t.Cells[2].Value));
        
        amt=total-_total;
        
        pdoc=new iTextSharp.text.Document(PageSize.A4,20f,20f,30f,30f);
        pwriter=PdfWriter.GetInstance(pdoc,new FileStream(@"F:\test.pdf",FileMode.Create));
        pdoc.Open();
        
        
        iTextSharp.text.Paragraph pg=new iTextSharp.text.Paragraph("DREAMLAND",myfont);
        pg.Alignment=Element.ALIGN_CENTER;
        pdoc.Add(pg);
        
        iTextSharp.text.Paragraph _pg=new iTextSharp.text.Paragraph("A Unit Of LA LA LAND",_myfont);
        _pg.Alignment=Element.ALIGN_CENTER;
        pdoc.Add(_pg);


        iTextSharp.text.Paragraph pg2=new iTextSharp.text.Paragraph("2/221, Tahira Road, Gr Floor, Rajouri Garden, New Delhi-110069",myfont2);
        pg2.Alignment=Element.ALIGN_CENTER;
        pdoc.Add(pg2);
        
        
        iTextSharp.text.Paragraph lineSeparator = new iTextSharp.text.Paragraph(new Chunk(new iTextSharp.text.pdf.draw.LineSeparator(0.0F, 100.0F, iTextSharp.text.BaseColor.BLACK, Element.ALIGN_LEFT, 1)));
        lineSeparator.SetLeading(0.5F, 0.5F);
        pdoc.Add(lineSeparator);
        
        
        iTextSharp.text.Paragraph pg3=new iTextSharp.text.Paragraph("\nDate: "+ DateTime.Now.ToString("dd-MMM-yyyy")+"\n\n",myfont3);
        pg3.Alignment=Element.ALIGN_RIGHT;
        pdoc.Add(pg3);
        
        iTextSharp.text.Paragraph pg4=new iTextSharp.text.Paragraph("To\nM/s "+ kryptonComboBox1.Text+"\n"+lblCity.Text+"\n\n\n\nDear Sir,\n\nPlease find enclosed herewith the payment for Rs. "+String.Format(new CultureInfo( "en-IN", false ), "{0:n}", Convert.ToDouble(amt))+" through paythru of your following bills\n\n",myfont4);
        pg4.Alignment=Element.ALIGN_LEFT;
        pdoc.Add(pg4);

        
        PdfPTable tab = new PdfPTable(billsDGV.ColumnCount);
        
        tab.WidthPercentage = 75;
        tab.DefaultCell.Padding = 3;
        tab.HorizontalAlignment = Element.ALIGN_CENTER;
        
        PdfPCell headcell = new PdfPCell(new Phrase(kryptonComboBox1.Text,headerFont));
        headcell.BackgroundColor = new BaseColor(255, 255, 30);
        headcell.Colspan=3;
        headcell.HorizontalAlignment=Element.ALIGN_CENTER;
        tab.AddCell(headcell);
        
        PdfPTable pdfTable = new PdfPTable(billsDGV.ColumnCount);
        
        pdfTable.DefaultCell.Padding = 3;
        pdfTable.WidthPercentage = 75;
        pdfTable.HorizontalAlignment = Element.ALIGN_CENTER;
        
        foreach (DataGridViewColumn column in billsDGV.Columns)
        {
            PdfPCell cell = new PdfPCell(new Phrase(column.HeaderText,headerFont));
            cell.BackgroundColor = new BaseColor(137, 220, 165);
            pdfTable.AddCell(cell);
        }


        foreach (DataGridViewRow row in billsDGV.SelectedRows.OfType<DataGridViewRow>().OrderBy(s=>s.Index))
        {
            foreach (DataGridViewCell cell in row.Cells)
            {
                pdfTable.AddCell(new Phrase(cell.Value.ToString(),standardFont));
            }
        }
        
        pdoc.Add(tab);
        pdoc.Add(pdfTable);
        
        return pdoc;
        
    }
    
//Generates the second table taking data from billsDGV & creditNotesDGV when items from both the DGV's are selected
    public iTextSharp.text.Document Gen2ndTable(iTextSharp.text.Document doc)
    {
        PdfPTable tabl = new PdfPTable(3);
        
        
        tabl.WidthPercentage = 75;
        tabl.DefaultCell.Padding = 3;
        
        PdfPCell b2_cell = new PdfPCell(new Phrase("",blankFont));
        b2_cell.HorizontalAlignment=Element.ALIGN_CENTER;
        b2_cell.Colspan=2;
        tabl.AddCell(b2_cell);

        
        PdfPCell b4_cell = new PdfPCell();
        Chunk _c = new Chunk(total.ToString(),headerFont);
        _c.SetUnderline(1,12);
        b4_cell.AddElement(_c);
        
        tabl.AddCell(b4_cell);


        PdfPCell a_cell = new PdfPCell(new Phrase("Less Credit Note/Debit Note",headerFont));
        a_cell.Colspan=3;
        a_cell.HorizontalAlignment=Element.ALIGN_CENTER;
        tabl.AddCell(a_cell);
        
        PdfPTable tab2 = new PdfPTable(creditNotesDGV.ColumnCount);
        
        tab2.WidthPercentage = 75;
        tab2.DefaultCell.Padding = 3;
        tab2.HorizontalAlignment = Element.ALIGN_CENTER;
        
        int j = 0;

        foreach (DataGridViewColumn column in creditNotesDGV.Columns)
        {
            j++;
            PdfPCell cell = new PdfPCell(new Phrase(column.HeaderText,headerFont));
            tab2.AddCell(cell);
        }

        foreach (DataGridViewRow row in creditNotesDGV.SelectedRows.OfType<DataGridViewRow>().OrderBy(s=>s.Index))
        {
            j = 0;
            foreach (DataGridViewCell cell in row.Cells)
            {
                j++;
                tab2.AddCell(new Phrase(cell.Value.ToString(),standardFont));
            }
        }

        PdfPTable _tabl = new PdfPTable(3);

        _tabl.WidthPercentage = 75;
        _tabl.DefaultCell.Padding = 3;
        _tabl.HorizontalAlignment = Element.ALIGN_CENTER;

        PdfPCell x1_cell = new PdfPCell(new Phrase(total.ToString(),blankFont));
        x1_cell.Colspan=2;
        _tabl.AddCell(x1_cell);

        PdfPCell x4_cell = new PdfPCell();
        Chunk c = new Chunk(_total.ToString(),headerFont);
        c.SetUnderline(1,12);
        x4_cell.AddElement(c);
        _tabl.AddCell(x4_cell);
        
        doc.Add(tabl);
        doc.Add(tab2);
        doc.Add(_tabl);
        
        return doc;
    }
    
//Generates the lower end part
    public void GenLastPart()
    {
        iTextSharp.text.Paragraph tot = new iTextSharp.text.Paragraph();
        Phrase phrase = new Phrase();
        phrase.Add(new Chunk("Total:   Rs. ",  totalfont));
        phrase.Add(new Chunk(String.Format(new CultureInfo( "en-IN", false ), "{0:n}", Convert.ToDouble(amt)), totalfont));
        
        
        tot.Add(phrase);
        PdfPTable totTbl = new PdfPTable(1);
        totTbl.TotalWidth = 200;
        PdfPCell tot_cell = new PdfPCell(tot);
        tot_cell.Border = iTextSharp.text.Rectangle.TOP_BORDER| iTextSharp.text.Rectangle.BOTTOM_BORDER;
        totTbl.AddCell(tot_cell);
        totTbl.WriteSelectedRows(0, -1, 290, 190, pwriter.DirectContent);
        
        iTextSharp.text.Paragraph copyright = new iTextSharp.text.Paragraph("Kindly acknowledge receipt of the same.\n\nThanking you,\n\nYours faithfully,\nfor DREAMLAND\n\n\n(Agatha Darkness)", myfont4);
        PdfPTable footerTbl = new PdfPTable(1);
        footerTbl.TotalWidth = 300;
        PdfPCell _cell = new PdfPCell(copyright);
        _cell.Border = 0;
        footerTbl.AddCell(_cell);
        footerTbl.WriteSelectedRows(0, -1, 10, 150, pwriter.DirectContent);
    }

I've used iText5 for PDF creation & .Net 4.5. How can I make my code more organized & efficient ?

\$\endgroup\$

1 Answer 1

1
+50
\$\begingroup\$

To have a more readable, and flexible code, you need to follow coding best practices. As the current code is not readable; because it lakes a good naming convention. Several names are either short or not clear and might have mixing between global and scoped variables naming conventions. This is my biggest concern. This is a great start of C# Coding Conventions.

for code redundancy, you could use extension methods to extend Document which you can create a simple fluent API that would make thigs much readable, and shorter. So, for insance, you can translate Gen1stTable code into something like this :

document
    .AddParagraph("DREAMLAND", titleFont)
    .AddParagraph("A Unit Of LA LA LAND", subtitleFont)
    .AddParagraph("2/221, Tahira Road, Gr Floor, Rajouri Garden, New Delhi-110069", subtitle2Font)
    .AddLineSeparator()
    .AddParagraph($"\nDate: {DateTime.Now.ToDefaultStringFormat()}\n\n", smallFont, Alignment.Right);
    .AddParagraph($"To\nM/s {customerName}\n{customerCity}\n\n\n\nDear Sir,\n\nPlease find enclosed herewith the payment for Rs. {totalAmount.ToDefaultStringFormat()} through paythru of your following bills\n\n", _timesRomanNormal)
    .AddTable(billsDGV.ColumnCount, table =>
    {
        table.AddPhrase(customerName, _tableHeaderFont, 3, Alignment.Center);
    })
    .AddTable(billsDGV, _tableHeaderFont, new BaseColor(137, 220, 165), _standardFont);

To do this, you can extend Document using extension methods, and customize the methods as it fits your work.

public enum Alignment
{
    Undefined = -1,
    Left = 0,
    Center = 1,
    Right = 2,
    Justified = 3,
    Top = 4,
    Middle = 5,
    Bottom = 6,
    Baseline = 7,
    JustifiedAll = 8
}

public static class TextSharpHelper
{
    public static readonly iTextSharp.text.Font TimesRomanNormal = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 12, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
    public static readonly iTextSharp.text.Font BlankFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 9, iTextSharp.text.Font.BOLD | iTextSharp.text.Font.UNDERLINE, BaseColor.WHITE);
    public static iTextSharp.text.Document AddParagraph(this iTextSharp.text.Document document, string text, iTextSharp.text.Font font, Alignment alignment = Alignment.Center)
    {
        var paragraph = new iTextSharp.text.Paragraph(text, font)
        {
            Alignment = (int)alignment
        };

        document.Add(paragraph);
        return document;
    }

    public static iTextSharp.text.Document AddLineSeparator(this iTextSharp.text.Document document)
    {
        var line = new iTextSharp.text.pdf.draw.LineSeparator(0.0F, 100.0F, BaseColor.BLACK, Element.ALIGN_LEFT, 1);
        var lineSeparator = new iTextSharp.text.Paragraph(new iTextSharp.text.Chunk(line));
        lineSeparator.SetLeading(0.5F, 0.5F);
        document.Add(lineSeparator);
        return document;
    }

    public static iTextSharp.text.pdf.PdfWriter AddTable(this iTextSharp.text.pdf.PdfWriter writer, int columns, int rowStart, int rowEnd, float xPos, float yPos, Action<iTextSharp.text.pdf.PdfPTable> action)
    {
        var table = new iTextSharp.text.pdf.PdfPTable(columns);

        action.Invoke(table);

        table.WriteSelectedRows(rowStart, rowEnd, xPos, yPos, writer.DirectContent);

        return writer;
    }




    public static iTextSharp.text.Document AddTable(this iTextSharp.text.Document document, int columns, Action<iTextSharp.text.pdf.PdfPTable> action)
    {
        var table = new iTextSharp.text.pdf.PdfPTable(columns)
        {
            WidthPercentage = 75
        };

        table.DefaultCell.Padding = 3;

        table.HorizontalAlignment = Element.ALIGN_CENTER;

        action.Invoke(table);

        document.Add(table);

        return document;
    }

    public static iTextSharp.text.Document AddTable(this iTextSharp.text.Document document, DataGridView gridView, iTextSharp.text.Font headerFont, BaseColor headerBackgroundColor, iTextSharp.text.Font bodyFont)
    {
        var table = new iTextSharp.text.pdf.PdfPTable(gridView.ColumnCount)
        {
            WidthPercentage = 75
        };

        table.DefaultCell.Padding = 3;

        table.HorizontalAlignment = Element.ALIGN_CENTER;

        foreach (DataGridViewColumn column in gridView.Columns)
        {
            var cell = new iTextSharp.text.pdf.PdfPCell(new iTextSharp.text.Phrase(column.HeaderText, headerFont))
            {
                BackgroundColor = headerBackgroundColor
            };

            table.AddCell(cell);
        }

        foreach (DataGridViewRow row in gridView.SelectedRows.OfType<DataGridViewRow>().OrderBy(s => s.Index))
        {
            foreach (DataGridViewCell cell in row.Cells)
            {
                table.AddCell(new iTextSharp.text.Phrase(cell.Value.ToString(), bodyFont));
            }
        }

        document.Add(table);

        return document;
    }

    public static iTextSharp.text.pdf.PdfPTable AddEmptyCell(this iTextSharp.text.pdf.PdfPTable table, int colspan)
    {
        var cell = new iTextSharp.text.pdf.PdfPCell(new iTextSharp.text.Phrase(string.Empty, BlankFont))
        {
            HorizontalAlignment = Element.ALIGN_CENTER,
            Colspan = colspan
        };

        table.AddCell(cell);
        return table;
    }

    public static iTextSharp.text.pdf.PdfPTable AddPhrase(this iTextSharp.text.pdf.PdfPTable table, string text, iTextSharp.text.Font font, int colspan, Alignment alignment = Alignment.Center)
    {
        var cell = new iTextSharp.text.pdf.PdfPCell(new iTextSharp.text.Phrase(text, font))
        {
            Colspan = colspan,
            HorizontalAlignment = (int)alignment
        };

        table.AddCell(cell);
        return table;
    }
    public static iTextSharp.text.pdf.PdfPTable AddPhrase(this iTextSharp.text.pdf.PdfPTable table, string text, iTextSharp.text.Font font, Action<iTextSharp.text.pdf.PdfPCell, iTextSharp.text.Phrase> action)
    {
        var phrase = new iTextSharp.text.Phrase(text, font);

        var cell = new iTextSharp.text.pdf.PdfPCell();
        
        action.Invoke(cell, phrase);
        
        cell.Column.AddText(phrase);
            
        table.AddCell(cell);
        
        return table;
    }


    public static iTextSharp.text.pdf.PdfPTable AddStrongUnderlinedPhrase(this iTextSharp.text.pdf.PdfPTable table, string text, iTextSharp.text.Font font)
    {
        var cell = new iTextSharp.text.pdf.PdfPCell();
        var chunck = new iTextSharp.text.Chunk(text, font);
        chunck.SetUnderline(1, 12);
        cell.AddElement(chunck);
        table.AddCell(cell);
        return table;
    }
}

Element.ALIGN_xxx are just integers, so we can use enum as a replacement to increase the readability. That's why I did Alignment enum.

The other helpful extensions that you may need are Formatting and DataGridView extension methods.

public static class FormatExtensions
{
    public static string ToDefaultStringFormat(this decimal number)
    {
        return number.ToString("N2", new CultureInfo("en-IN", false));
    }

    public static string ToDefaultStringFormat(this DateTime date)
    {
        return date.ToString("dd-MMM-yyyy");
    }

}

public static class DataGridViewExtensions
{
    public static decimal SumSelectedRows(this DataGridView gridView, int cellIndex)
    {
        return gridView.SelectedRows.OfType<DataGridViewRow>().Sum(t => Convert.ToDecimal(t.Cells[cellIndex].Value));
    }
}

Now, the only thing left is just to try reduce code redundancy by following the same ideas, and if there are multiple places that you see there are some repeated strings or code, then it's time to unify them into one place and reuse them.

The other thing that I should not out, Document implements IDisposal so you should use using clause on it to dispose it correctly.

here is a revised sample of your code (not tested, but it should give you the boost you're looking for) :

/// <summary>
/// Description of TextSharpExample.
/// </summary>
public class TextSharpExample
{
    private readonly iTextSharp.text.Font _timesRomanNormal = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 12, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
    private readonly iTextSharp.text.Font _tableHeaderFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 9, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
    private readonly iTextSharp.text.Font _helveticaFontSamllStandard = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 9, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);

    /// <summary>
    /// Generates the document's header
    /// </summary>
    /// <param name="document"></param>
    private void GenerateHeader(iTextSharp.text.Document document)
    {
        var titleFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 20, iTextSharp.text.Font.BOLD, BaseColor.BLUE);
        var subtitleFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 14, iTextSharp.text.Font.BOLD, BaseColor.BLUE);
        var subtitle2Font = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 11, iTextSharp.text.Font.NORMAL, BaseColor.RED);
        var smallFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 9, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);

        document
            .AddParagraph("DREAMLAND", titleFont)
            .AddParagraph("A Unit Of LA LA LAND", subtitleFont)
            .AddParagraph("2/221, Tahira Road, Gr Floor, Rajouri Garden, New Delhi-110069", subtitle2Font)
            .AddLineSeparator()
            .AddParagraph(string.Format("\nDate:{0}\n\n", DateTime.Now.ToDefaultStringFormat()), smallFont, Alignment.Right);
    }

    /// <summary>
    /// For generating the Bills and Credits tables
    /// </summary>
    /// <param name="document"></param>
    /// <param name="gridView"></param>
    /// <param name="total"></param>
    /// <param name="headerText"></param>
    /// <param name="primaryHeaderBackgroundColor"></param>
    /// <param name="secondaryHeaderBackgroundColor"></param>
    /// <returns></returns>
    private iTextSharp.text.Document GenerateTable(iTextSharp.text.Document document, DataGridView gridView, decimal total, string headerText, BaseColor primaryHeaderBackgroundColor, BaseColor secondaryHeaderBackgroundColor)
    {
        if (gridView.SelectedRows.Count > 0)
        {
            var columnsCount = gridView.Columns.Count;

            // Generate bills table 
            return document
                .AddTable(columnsCount, table =>                    
                {
                    table.AddPhrase(headerText, _tableHeaderFont, (cell, phrase) =>
                    {
                        cell.BackgroundColor = primaryHeaderBackgroundColor;
                        cell.Colspan = columnsCount;
                        cell.HorizontalAlignment = (int)Alignment.Center;
                    });
                })
                .AddTable(gridView, _tableHeaderFont, secondaryHeaderBackgroundColor, _helveticaFontSamllStandard)
                .AddTable(columnsCount, table =>
                {
                    table
                    .AddEmptyCell(columnsCount - 1)
                    .AddStrongUnderlinedPhrase(total.ToDefaultStringFormat(), _tableHeaderFont);
                });

        }

        return document;
    }
    /// <summary>
    /// Generates the document's body
    /// </summary>
    /// <param name="document"></param>
    /// <param name="customerName"></param>
    /// <param name="customerCity"></param>
    /// <param name="totalAmount"></param>
    private void GenerateBody(iTextSharp.text.Document document, PdfWriter writer, string customerName, string customerCity, DataGridView biilsDataGridView, DataGridView creditNotesDataGridView)
    {
        var totalBills = biilsDataGridView.SumSelectedRows(2);
        var totalCreditNotes = creditNotesDataGridView.SumSelectedRows(2);
        var totalAmount = totalBills - totalCreditNotes;
        
        // since it's a long string, declaring it in a local variable will improve readibility.
        var bodyStartParagraph = string.Format("To\nM/s {0}\n{1}\n\n\n\nDear Sir,\n\nPlease find enclosed herewith the payment for Rs. {2} through paythru of your following bills\n\n", customerName, customerCity, totalAmount.ToDefaultStringFormat());
        
        // Generate body's paragraph
        document.AddParagraph(bodyStartParagraph, _timesRomanNormal, Alignment.Left);

        // Generate bills table 
        GenerateTable(document, biilsDataGridView, totalBills, customerName, new BaseColor(255, 255, 30), new BaseColor(137, 220, 165));

        // Generate credits table
        GenerateTable(document, creditNotesDataGridView, totalCreditNotes, "Less Credit Note/Debit Note", BaseColor.WHITE, BaseColor.WHITE);

        // Generate the end of document
        writer.AddTable(1, 0, -1, 290, 190, table =>
        {
            table.TotalWidth = 200;
            
            var totalPhrase = string.Format("Total:   Rs. {0}", totalAmount.ToDefaultStringFormat());

            table.AddPhrase(totalPhrase, new Font(Font.FontFamily.TIMES_ROMAN, 12f, Font.BOLD), (cell, phrase) =>
            {
                cell.Border = Rectangle.TOP_BORDER | Rectangle.BOTTOM_BORDER;
            });
        })
        .AddTable(1, 0, -1, 10, 150, table =>
        {
            table.TotalWidth = 300;
            
            var appreciationPhrase = "Kindly acknowledge receipt of the same.\n\nThanking you,\n\nYours faithfully,\nfor DREAMLAND\n\n\n(Agatha Darkness)";

            table.AddPhrase(appreciationPhrase, _timesRomanNormal, (cell, phrase) =>
            {
                cell.Border = 0;

            });
        });

    }

    public void GenerateDocument(string filePath, string customerName, string customerCity, DataGridView biilsDataGridView, DataGridView creditNotesDataGridView)
    {

        var document = new iTextSharp.text.Document(PageSize.A4, 20f, 20f, 30f, 30f);
        var fileStream = new System.IO.FileStream(filePath, FileMode.Create);
        var writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, fileStream);

        try
        {
            // Open the document to enable you to write to the document  
            document.Open();
            // Add a simple and wellknown phrase to the document in a flow layout manner  
            GenerateHeader(document);

            GenerateBody(document, writer, customerName, customerCity, biilsDataGridView, creditNotesDataGridView);
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message, ex);
        }
        finally
        {
            // .NET 4.5 support

            if (document != null)
            {
                document.Dispose();
            }

            if (writer != null)
            {
                writer.Dispose();
            }

            if (fileStream != null)
            {
                fileStream.Dispose();
            }
        }

    }
}

Usage :

var invoice = new TextSharpExample();
var filePath = @"F:\test.pdf";

invoice.GenerateDocument(filePath, kryptonComboBox1.Text, lblCity.Text, billsDGV, creditNotesDGV);

Process.Start(filePath);
\$\endgroup\$
1
  • \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$ Commented Feb 6, 2022 at 6:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.