0

I am using a custom object and trying to write the data into a pdf to generate an invoice. However, im getting certain errors, and am not able to write a few things to the document. It would be very grateful if anyone could help me out of this. Here is my code:

public string InvoiceGenerator()
    {
        string random = (new Random().Next(1, 100)).ToString();
        string virtualFilename = ConfigurationManager.AppSettings["InvoiceDirectoryFullPath"] + "/" + random + ".pdf";
        string absolutefilePath = System.Web.Hosting.HostingEnvironment.MapPath(virtualFilename);
        using (FileStream fs = new FileStream(absolutefilePath, FileMode.Create))
        {
            Document document = new Document(PageSize.A4, 25, 25, 30, 10);//left,right,top,bottom margins
            try
            {



                using (PdfWriter writer = PdfWriter.GetInstance(document, fs))//;
                {
                    document.Open();
                    if (company == null || client == null || project == null)
                        throw new Exception("Company/Client/Project Data is not present!!");

                    Paragraph p1 = new Paragraph();

                    string x = System.Web.Hosting.HostingEnvironment.MapPath(company.LogoUrl);
                    iTextSharp.text.Image companyLogo = iTextSharp.text.Image.GetInstance(x);
                    companyLogo.ScaleAbsolute(new Rectangle(100, 100));
                    companyLogo.SetAbsolutePosition(25, 740);

                    PdfContentByte cb = writer.DirectContent;
                    cb.AddImage(companyLogo);
                    //surround by a rectangle
                    cb.Rectangle(25, 740, 100, 100);
                    cb.Stroke();
                    //text begins here
                    //select font
                    BaseFont f_cb = BaseFont.CreateFont("c:\\windows\\fonts\\calibrib.ttf", BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
                    BaseFont f_cn = BaseFont.CreateFont("c:\\windows\\fonts\\calibri.ttf", BaseFont.CP1252, BaseFont.NOT_EMBEDDED);



                    //write comapny data
                    writeTextLeftAligned(cb, company.Address, 25, 720, f_cn, 10);
                    writeTextLeftAligned(cb, "o. " + company.PhoneNumber, 25, 710, f_cn, 10);
                    writeTextLeftAligned(cb, "f. " + company.FaxNumber, 25, 700, f_cn, 10);
                    writeTextLeftAligned(cb, company.EmailId, 25, 690, f_cn, 10);


                    //now write the client and project data
                    writeTextRightAligned(cb, "Claim to: " + client.Name, 540, 730, f_cn, 10);
                    writeTextRightAligned(cb, project.Name, 540, 720, f_cn, 10);
                    writeTextRightAligned(cb, client.Address, 540, 710, f_cn, 10);

                    //pre-set text below:
                    //iTextSharp.text.Font boldFontCalibri=new iTextSharp.text.Font(f_cn, 12, iTextSharp.text.Font.BOLD, iTextSharp.text.BaseColor.BLACK);
                    writeTextLeftAlignedInBold(cb, "INVOICE NUMBER: " + random, 25, 670, f_cn, 12);
                    writeTextLeftAlignedInBold(cb, "PAYMENT TERM STRICTLY 30 DAYS", 225, 670, f_cn, 12);
                    writeTextRightAlignedInBold(cb, "Purchase order number: #", 540, 670, f_cn, 12);
                    writeTextRightAlignedInBold(cb, "NA", 540, 654, f_cn, 12);
                    writeTextLeftAligned(cb, company.Description, 40, 120, f_cn, 12);
                    //add the legal text at the bottom
                    writeTextLeftAligned(cb, company.Description, 40, 120, f_cn, 12);
                    //now add total GST and subtotal

                   writeFooterText(cb, company.CompanyInvoiceLegalText, f_cn, 6);
                    double subtotal = 0.0;

                    foreach (DocketEntity docket in dockets)
                    {
                        foreach (MachineTimeLogs machineLog in docket.MachinetimeLogsInDocket)
                        {
                            subtotal += machineLog.OperationCharge;
                        }
                    }

                    foreach (DocketEntity docket in dockets)
                    {
                        foreach (AttachmentTimeLogs attachmentLog in docket.AttachmentTimeLogsInDocket)
                        {
                            subtotal += attachmentLog.OperationCharge;
                        }
                    }

                    subtotal = Math.Round(subtotal, 2);
                    writeTextRightAlignedInBold(cb, "Subtotal:  $" + subtotal.ToString(), 460, 170, f_cn, 12);
                    double GST = (Convert.ToDouble(ConfigurationManager.AppSettings["GSTRate"])) * subtotal / 100;
                    GST = Math.Round(GST, 2);
                    writeTextRightAlignedInBold(cb, "GST:  $" + GST.ToString(), 460, 150, f_cn, 12);
                    double total = subtotal + GST;
                    writeTextRightAlignedInBold(cb, "Total:  $" + total.ToString(), 460, 140, f_cn, 12);
                    writeTextRightAligned(cb, " ", 460, 100, f_cn, 2);

                    //add machine and attachement details and get subtotal;

                    //add machine table
                    PdfPTable machinetable = new PdfPTable(6);//6 columns
                    PdfPCell machineTableHeader = new PdfPCell(new Phrase("Machine details"));
                    machineTableHeader.Colspan = 6;
                    machineTableHeader.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
                    machinetable.AddCell(machineTableHeader);

                    machinetable.AddCell("Machine Name");
                    machinetable.AddCell("Docket Date");
                    machinetable.AddCell("Docket Number");
                    machinetable.AddCell("Hours");
                    machinetable.AddCell("Rate per hour");
                    machinetable.AddCell("Dollar value");

                    foreach (DocketEntity docket in dockets)
                    {
                        foreach (MachineTimeLogs machineLog in docket.MachinetimeLogsInDocket)
                        {
                            machinetable.AddCell(machineLog.MachineName);
                            machinetable.AddCell(docket.DateCreated.ToShortDateString());
                            machinetable.AddCell(docket.DocketId);
                            machinetable.AddCell(machineLog.OperationHours.ToString());
                            machinetable.AddCell("$ " + machineLog.RatePerHour.ToString());
                            machinetable.AddCell("$ " + machineLog.OperationCharge.ToString());
                            //subtotal += machineLog.OperationCharge;
                        }
                    }

                    //set machine columns width;
                    float[] machineTableColumnsWidths = { 150, 80, 80, 40, 40, 60 };
                    machinetable.SetTotalWidth(machineTableColumnsWidths);
                   // machinetable.WriteSelectedRows(0, machinetable.Rows.Count, 50, 640, cb);

                    //add attachment table
                    PdfPTable attachmentTable = new PdfPTable(6);
                    PdfPCell attachmentHeader = new PdfPCell(new Phrase("Attachment details"));
                    attachmentHeader.Colspan = 6;
                    attachmentHeader.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
                    attachmentTable.AddCell(attachmentHeader);
                    attachmentTable.AddCell("Attachment Name");
                    attachmentTable.AddCell("Docket Date");
                    attachmentTable.AddCell("Docket Number");
                    attachmentTable.AddCell("Hours");
                    attachmentTable.AddCell("Rate per hour");
                    attachmentTable.AddCell("Dollar value");

                    foreach (DocketEntity docket in dockets)
                    {
                        foreach (AttachmentTimeLogs attachmentLog in docket.AttachmentTimeLogsInDocket)
                        {
                            attachmentTable.AddCell(attachmentLog.AttachmentName);
                            attachmentTable.AddCell(docket.DateCreated.ToShortDateString());
                            attachmentTable.AddCell(docket.DocketId);
                            attachmentTable.AddCell(attachmentLog.HoursWorked.ToString());
                            attachmentTable.AddCell("$ " + attachmentLog.RatePerHour.ToString());
                            attachmentTable.AddCell("$ " + attachmentLog.OperationCharge.ToString());
                            //subtotal += attachmentLog.OperationCharge;
                        }
                    }

                    float[] attachmentTableColumnsWidths = { 150, 80, 80, 40, 40, 60 };
                    attachmentTable.SetTotalWidth(attachmentTableColumnsWidths);
                    //attachmentTable.WriteSelectedRows(0, attachmentTable.Rows.Count, 50, 460, cb);



                }

            }
            catch (ObjectDisposedException objectDisposed)
            {
                //GETTING ERROR HERE
            }

        }


       //the invoice pdf is created..now append the dockets pdf to this generated file
        //now add the appended files to the invoice
       string appendedInvoicePath= AppendDocketsToGeneratedInvoice(absolutefilePath);

       return appendedInvoicePath;//this is the virtual file path
    }


 private void writeFooterText(PdfContentByte cb, string text, BaseFont font, int Size)
    {
        try
        {

            cb.SetFontAndSize(font, Size);
            cb.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
            //cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, Text, X, Y, 0);

            ColumnText ct = new ColumnText(cb);
            ct.SetSimpleColumn(new Phrase(new Chunk(text)),
                               46, 36, 530, 56, 25, Element.ALIGN_CENTER | Element.ALIGN_TOP);
            ct.Go(); 

        }
        catch (Exception e)
        {
            throw e;
        }
    }



    private void writeTextLeftAligned(PdfContentByte cb, string Text, int X, int Y, BaseFont font, int Size)
    {
        try
        {

            cb.SetFontAndSize(font, Size);
            cb.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
            cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, Text, X, Y, 0);
         }
        catch (Exception e)
        {
            throw e;
        }
    }

    private void writeTextLeftAlignedInBold(PdfContentByte cb, string Text, int X, int Y, BaseFont font, int Size)
    {
       try
       {
           cb.SetFontAndSize(font, Size);
            cb.SetLineWidth(0.5);
            cb.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE); 
            cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, Text, X, Y, 0);
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    private void writeTextRightAligned(PdfContentByte cb, string Text, int X, int Y, BaseFont font, int Size)
    {
        try
        {
            cb.SetFontAndSize(font, Size);
            cb.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
            cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT, Text, X, Y, 0);
        }
        catch (Exception e)
        {
            throw e;
        }
    }
selva
  • 1,175
  • 1
  • 19
  • 39
  • The issue might come from two `using` constructions. `Dispose()` of `PdfWriter` closes the underlying stream, and it is also then closed by the corresponding `Dispose()` call of `FileStream`. So try to avoid two `using` contructions. Another way would be to try `document.CloseStream = false;` – Alexey Subach Jul 19 '16 at 08:35
  • 1
    Not related to your problem (and maybe your code is just a modified sample), but when you `throw e` in your catch statements you are "stomping the stack" which makes it harder to debug sometimes. Instead you should just `throw`. See [this](http://stackoverflow.com/a/178464/231316) for more. – Chris Haas Jul 19 '16 at 10:18
  • Have you tried removing all the instructions adding content to your pdf, replacing them by the addition of a simple paragraph? If that does not fail, add your original content additions piece by piece and check when it starts to fail. And if it still fails, complexity of the code to check is reduced. BTW, when constructing the `virtualFilename` I would use a backslash, not a slash, in .Net. – mkl Jul 20 '16 at 05:35

0 Answers0