Spire.PDF is a professional PDF library applied to creating, writing, editing, handling and reading PDF files without any external dependencies. Get free and professional technical support for Spire.PDF for .NET, Java, Android, C++, Python.

Tue Apr 21, 2026 3:13 pm

Here is my code:

Code: Select all
        SetLicense();
        PdfTrueTypeFont fontHeaderTitle = new PdfTrueTypeFont(new Font("Arial", 16.5f, FontStyle.Bold));
        PdfTrueTypeFont fontHeaderText = new PdfTrueTypeFont(new Font("Arial", 9f, FontStyle.Regular));
        PdfTrueTypeFont fontHeaderTinyTitle = new PdfTrueTypeFont(new Font("Arial", 7.5f, FontStyle.Bold));
        PdfTrueTypeFont fontHeaderTextBold = new PdfTrueTypeFont(new Font("Arial", 9f, FontStyle.Bold));
        PdfTrueTypeFont fontHeaderInvoiceTitle = new PdfTrueTypeFont(new Font("Times New Roman", 24f, FontStyle.Regular));
        PdfTrueTypeFont fontPaymentCredit = new PdfTrueTypeFont(new Font("Arial", 8.5f, FontStyle.Italic));
        PdfTrueTypeFont fontBodyText = new PdfTrueTypeFont(new Font("Arial", 9f, FontStyle.Regular));
        PdfTrueTypeFont fontBodyTextBold = new PdfTrueTypeFont(new Font("Arial", 9f, FontStyle.Bold));

        PdfStringFormat formatLeft = new PdfStringFormat(PdfTextAlignment.Left, PdfVerticalAlignment.Top);
        PdfStringFormat formatRight = new PdfStringFormat(PdfTextAlignment.Right, PdfVerticalAlignment.Top);
        PdfStringFormat formatCenter = new PdfStringFormat(PdfTextAlignment.Center, PdfVerticalAlignment.Top);

        Color clrLaurusDarkBlue = ColorTranslator.FromHtml("#082141");
        PdfRGBColor pdfColorLaurusDarkBlue = new PdfRGBColor(clrLaurusDarkBlue);
        PdfRGBColor pdfColorLightGrey = new PdfRGBColor(ColorTranslator.FromHtml("#DDDDDD"));
        PdfPen penThickHeading = new PdfPen(pdfColorLaurusDarkBlue, 30f);
        PdfPen penGridHeaderBackground = new PdfPen(pdfColorLightGrey, 20f);
        PdfPen penThinBlack = new PdfPen(PdfBrushes.Black, 0.25f);
        PdfPen penDescription = new PdfPen(PdfBrushes.Black, .00000001f);

        SizeF pageSize = PdfPageSize.Letter;

        // now create the PDF document
        PdfDocument doc = new PdfDocument();

        // document margins
        // document margins
        PdfUnitConvertor unitCvtr = new PdfUnitConvertor();
        PdfMargins margin = new PdfMargins();
        margin.Top = unitCvtr.ConvertUnits(0.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point);
        margin.Bottom = unitCvtr.ConvertUnits(0.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point);
        margin.Left = unitCvtr.ConvertUnits(0.25f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point);
        margin.Right = unitCvtr.ConvertUnits(0.25f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point);

        doc.Template.Top = new PdfPageTemplateElement(pageSize.Width, 300f);
        doc.Template.Top.Foreground = true;

        PdfImage pdfImage = PdfImage.FromFile(context.Request.PhysicalApplicationPath + "LogoInvoice.png");
        doc.Template.Top.Graphics.DrawImage(pdfImage, 0, 0);

        // keep track of vertical position
        float yHeader = 100;

        // header bar
        doc.Template.Top.Graphics.DrawLine(penThickHeading, 0, yHeader, pageSize.Width, yHeader);

        // header bar text
        doc.Template.Top.Graphics.DrawString(@"Laurus College", fontHeaderTitle, PdfBrushes.White, 10, yHeader-10, formatLeft);
        doc.Template.Top.Graphics.DrawString("INVOICE", fontHeaderInvoiceTitle, PdfBrushes.White, pageSize.Width - 10, yHeader-15, formatRight);

        // address
        yHeader += 15;
        doc.Template.Top.Graphics.DrawString(@"address redacted", fontHeaderText, PdfBrushes.Black, 0, yHeader, formatLeft);
        yHeader += (fontHeaderText.Height*3)+5;

        // SOLD TO:
        doc.Template.Top.Graphics.DrawString("SOLD TO:", fontHeaderTinyTitle, PdfBrushes.Black, 0, yHeader, formatLeft);
        yHeader += fontHeaderTinyTitle.Height+2;

        // Department of Veteran's Affairs
        doc.Template.Top.Graphics.DrawString(@"Department of Veteran's Affairs

CH 31 VR&E", fontHeaderText, PdfBrushes.Black, 0, yHeader, formatLeft);

        // RE:
        doc.Template.Top.Graphics.DrawString("RE:", fontHeaderTinyTitle, PdfBrushes.Black, 0, yHeader + 75, formatLeft);
        // Student Name
        doc.Template.Top.Graphics.DrawString(dataSet.Tables[0].Rows[0]["StudentName"].ToString(), fontHeaderTextBold, PdfBrushes.Black, 10, yHeader + 75 + fontHeaderTinyTitle.Height, formatLeft);

        // right side vertical seperation line
        doc.Template.Top.Graphics.DrawLine(penThinBlack, pageSize.Width - 125, yHeader, pageSize.Width - 125, yHeader + 100);

        // INVOICE NUMBER
        doc.Template.Top.Graphics.DrawString("INVOICE NUMBER", fontHeaderText, PdfBrushes.Black, pageSize.Width - 127, yHeader, formatRight);
        doc.Template.Top.Graphics.DrawString(dataSet.Tables[0].Rows[0]["InvoiceNumber"].ToString(), fontHeaderText, PdfBrushes.Black, pageSize.Width - 123, yHeader, formatLeft);

        // INVOICE DATE
        yHeader += fontHeaderText.Height*2;
        doc.Template.Top.Graphics.DrawString("INVOICE DATE", fontHeaderText, PdfBrushes.Black, pageSize.Width - 127, yHeader, formatRight);
        doc.Template.Top.Graphics.DrawString(Convert.ToDateTime(dataSet.Tables[0].Rows[0]["InvoiceDate"]).ToString("MMMM dd, yyyy"), fontHeaderText, PdfBrushes.Black, pageSize.Width - 123, yHeader, formatLeft);

        // DUE DATE
        yHeader -= fontHeaderText.Height*3;
        yHeader += 100;
        doc.Template.Top.Graphics.DrawString("DUE DATE", fontHeaderText, PdfBrushes.Black, pageSize.Width - 127, yHeader, formatRight);
        doc.Template.Top.Graphics.DrawString(Convert.ToDateTime(dataSet.Tables[0].Rows[0]["DueDate"]).ToString("MMMM dd, yyyy"), fontHeaderText, PdfBrushes.Black, pageSize.Width - 123, yHeader, formatLeft);

        yHeader += 50;

        // header is complete, now start the first page
        // create report's main section
        PdfSection section = doc.Sections.Add();
        section.PageSettings.Size = pageSize;
        section.PageSettings.Margins = margin;
        PdfNewPage page = section.Pages.Add();

        float yPage = 0;
        float fGridWidth = pageSize.Width - margin.Left - margin.Right;
        float fGridHeight = 300;

        // now onto the invoice items grid
        // header background light grey
        page.Canvas.DrawLine(penGridHeaderBackground, 0, yPage+10, pageSize.Width, yPage+10);
        // header top
        page.Canvas.DrawLine(penThinBlack, 0, yPage, pageSize.Width, yPage);
        // header bottom
        page.Canvas.DrawLine(penThinBlack, 0, yPage+20, pageSize.Width, yPage+20);
        // sides of grid
        page.Canvas.DrawLine(penThinBlack, 0, yPage, 0, yPage + fGridHeight);
        page.Canvas.DrawLine(penThinBlack, fGridWidth - penThinBlack.Width, yPage, pageSize.Width - margin.Left - margin.Right - penThinBlack.Width, yPage + fGridHeight);
        // bottom of grid
        page.Canvas.DrawLine(penThinBlack, 0, yPage + fGridHeight, fGridWidth - penThinBlack.Width, yPage + fGridHeight);
        // vertical columns of grid
        page.Canvas.DrawLine(penThinBlack, fGridWidth * .12f, yPage + 20, fGridWidth * .12f, yPage + fGridHeight);
        page.Canvas.DrawLine(penThinBlack, fGridWidth * .65f, yPage + 20, fGridWidth * .65f, yPage + fGridHeight);
        page.Canvas.DrawLine(penThinBlack, fGridWidth * .80f, yPage + 20, fGridWidth * .80f, yPage + fGridHeight);


        // header headings
        float fCenterHeadings = fGridWidth * .06f;
        page.Canvas.DrawString("QUANTITY", fontHeaderTinyTitle, PdfBrushes.Black, fCenterHeadings, yPage + 5, formatCenter);
        fCenterHeadings = fGridWidth * .385f;
        page.Canvas.DrawString("DESCRIPTION", fontHeaderTinyTitle, PdfBrushes.Black, fCenterHeadings, yPage + 5, formatCenter);
        fCenterHeadings = fGridWidth * .725f;
        page.Canvas.DrawString("UNIT PRICE", fontHeaderTinyTitle, PdfBrushes.Black, fCenterHeadings, yPage + 5, formatCenter);
        fCenterHeadings = fGridWidth * .9f;
        page.Canvas.DrawString("AMOUNT", fontHeaderTinyTitle, PdfBrushes.Black, fCenterHeadings, yPage + 5, formatCenter);

        // items inside the grid
        yPage += 40;
        foreach (DataRow row in dataSet.Tables[1].Rows)
        {
            // quantity
            page.Canvas.DrawString(row["Quantity"].ToString(), fontBodyText, PdfBrushes.Black, fGridWidth * .06f, yPage, formatCenter);
            // description
            RectangleF rDescription = new RectangleF();
            rDescription.Width = fGridWidth * .53f - 10;
            rDescription.X = fGridWidth * .12f + 5;
            rDescription.Y = yPage;
            rDescription.Height = yPage + (fontBodyText.Height * 2);
            PdfStringFormat formatDescription = new PdfStringFormat();
            formatDescription.WordWrap = PdfWordWrapType.Word;
            formatDescription.Alignment = PdfTextAlignment.Left;
            page.Canvas.DrawString(row["Description"].ToString(), fontBodyText, penDescription, PdfBrushes.Black, rDescription, formatDescription);
            // unit price
            page.Canvas.DrawString(row["UnitPrice"].ToString(), fontBodyText, PdfBrushes.Black, (fGridWidth * .8f) - 5, yPage, formatRight);
            // amount
            page.Canvas.DrawString(row["Amount"].ToString(), fontBodyText, PdfBrushes.Black, fGridWidth - 5, yPage, formatRight);
            // add empty space
            yPage += (fontBodyText.Height * 2) + 10;
        }


        yPage += 20;



        // output the report
        context.Response.ContentType = "application/pdf";
        context.Response.AddHeader("Content-Disposition", $"attachment;filename=Invoice {dataSet.Tables[0].Rows[0]["InvoiceNumber"].ToString()}.pdf");
        MemoryStream ms = new MemoryStream();
        doc.SaveToStream(ms);
        ms.Position = 0;
        ms.CopyTo(context.Response.OutputStream);
        context.Response.Flush();
        context.Response.End();

        doc.Close();
        doc.Dispose();
        doc = null;
        ms.Dispose();
        ms = null;


The problem is this line of code is rendering BOLD text. It should be just like the fontBodyText property. Normal. not bold. But notice I am using a rectangle with word wrapping because the description can overflow one line area of the "grid".

Code: Select all
            page.Canvas.DrawString(row["Description"].ToString(), fontBodyText, penDescription, PdfBrushes.Black, rDescription, formatDescription);

penDescription is declared as such (although it's in my code near the top, I mention it again)

Code: Select all
        PdfPen penDescription = new PdfPen(PdfBrushes.Black, .00000001f);

I have tried everything under the sun here and can't find a fix.

Here is a screen shot excerpt of the problem area:

Untitled.png

perryway
 
Posts: 7
Joined: Wed Jan 04, 2017 7:42 pm

Wed Apr 22, 2026 3:17 am

Hello,

Thank you for your inquiry,
Using PdfPen itself has a certain edge effect, but I tested your scenarios and found that the effect is much better. Which Spire.PDF version you are currently using? At the same time, you can directly use "page.Canvas.DrawString(row["Description"].ToString(), fontBodyText, PdfBrushes.Black, rDescription, formatDescription);", here are the test results from my end for your reference. If you also encounter problems using this method, just feel free to write back.
out.png

Code: Select all
       PdfDocument doc = new PdfDocument();
       PdfUnitConvertor unitCvtr = new PdfUnitConvertor();
       PdfMargins margin = new PdfMargins();
       margin.Top = unitCvtr.ConvertUnits(0.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point);
       margin.Bottom = unitCvtr.ConvertUnits(0.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point);
       margin.Left = unitCvtr.ConvertUnits(0.25f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point);
       margin.Right = unitCvtr.ConvertUnits(0.25f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point);

       PdfSection section = doc.Sections.Add();
       section.PageSettings.Margins = margin;
       PdfNewPage page = section.Pages.Add();
       PdfTrueTypeFont fontBodyText = new PdfTrueTypeFont(new System.Drawing.Font("Arial", 9f, FontStyle.Regular));
       PdfPen penDescription = new PdfPen(PdfBrushes.Black, 0.000000001f);
       PdfStringFormat formatDescription = new PdfStringFormat();
       formatDescription.WordWrap = PdfWordWrapType.Word;
       formatDescription.Alignment = PdfTextAlignment.Left;
       //Original way
      // page.Canvas.DrawString("DescriptionSampleTest", fontBodyText, penDescription, PdfBrushes.Black, new RectangleF(10, 10, 100, 100), formatDescription);

       //Another way
       page.Canvas.DrawString("DescriptionSampleTest", fontBodyText, PdfBrushes.Black, new RectangleF(10,10,100,100), formatDescription);
       doc.SaveToFile("outAnother.pdf", Spire.Pdf.FileFormat.PDF);

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1536
Joined: Wed Apr 25, 2018 3:20 am

Fri Apr 24, 2026 5:57 pm

I found much later on that you have an overload that doesn't use PdfPen but only PdfBrush like other calls I've made. So I adjusted by using that and it looks like normal thickness now. I think the PdfPen is unable to make the font behave like normal, adding as you said an "edge" to it.

perryway
 
Posts: 7
Joined: Wed Jan 04, 2017 7:42 pm

Mon Apr 27, 2026 1:21 am

Hello,

Thank you for your feedback,
Yes, DrawString() method supports multiple overload parameter settings, different parameter settings can be selected according to different scenarios. If some fonts do not have bold font, it can use PdfPen to simulate the bold effect.
If you encounter any other problems during use, just feel free to contact.

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1536
Joined: Wed Apr 25, 2018 3:20 am

Return to Spire.PDF

cron