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 Jul 28, 2020 4:32 pm

I am attempting to add a right-aligned section page number to the footer of a pdf document I am creating from scratch. From the sample center and online tutorials, I was able to add a page number, and it looks as desired on pages 1-9, eg. “Page 1 of 10”, but on page ten, the page number appears as “Page 10 of 1”. When I modify the location of the field to elsewhere in the footer, the text appears as expected.

Of note, when I set the x value of the field’s location to 0, it appears as left aligned in the footer, even with the left side of the table generated, despite the StringFormat property specifying that the text should be right-aligned. I tried changing the property to left alignment and it had no effect on the resulting pdf.

Elsewhere, I am writing to the header and footer with Graphics.DrawString() instead of PdfCompositeField.Draw(), and it is functioning as expected with both left and center aligned text; it is only PdfCompisiteField.Draw() that I can’t get working correctly.

Also, in the sample code below, the section template widths do not match the width of the templates in the sample center or online tutorials. Setting the template.Bottom width to the full page width caused the page number to be written to the right of the printable space and not to appear.

I am using version 6.7.8 of the dlls. The Sample Center lists version 6.1.4, but all the relevant code is the same as in the online tutorials.


Relevant code follows:


public MemoryStream GetReport(Dictionary<string, DataTable> RptTables)
{
PdfDocument doc = new PdfDocument();
PdfUnitConvertor unitConvert = new PdfUnitConvertor();



PdfBrush FooterBrush = PdfBrushes.Gray;
PdfPen FooterPen = new PdfPen(FooterBrush, 0.75f);
PdfTrueTypeFont FooterFont = new PdfTrueTypeFont(new Font("Arial", 9f, FontStyle.Italic), true);
PdfStringFormat FooterFmtRight = new PdfStringFormat(PdfTextAlignment.Right);
PdfStringFormat FooterFmtLeft = new PdfStringFormat(PdfTextAlignment.Left);

PdfTrueTypeFont HeaderFont = new PdfTrueTypeFont(new Font("Arial", 16f, FontStyle.Bold));
PdfStringFormat HeaderFormat = new PdfStringFormat(PdfTextAlignment.Center, PdfVerticalAlignment.Top);
PdfBrush HeaderBrush = PdfBrushes.Black;


float FooterBuffer = FooterFont.Height * 0.75f;
float HeaderBuffer = HeaderFont.Height * 0.75f;

float FooterOffset = FooterBuffer + FooterFont.Height;
float HeaderOffset = HeaderBuffer + HeaderFont.Height;




PdfMargins margins = new PdfMargins()
{
Top = unitConvert.ConvertUnits(.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point) + HeaderOffset,
Bottom = unitConvert.ConvertUnits(.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point) + FooterOffset,
Left = unitConvert.ConvertUnits(.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point),
Right = unitConvert.ConvertUnits(.5f, PdfGraphicsUnit.Inch, PdfGraphicsUnit.Point)
};


PdfPageSettings pageSettings = new PdfPageSettings();
pageSettings.Margins = margins;
pageSettings.Size = PdfPageSize.Letter;
pageSettings.Orientation = PdfPageOrientation.Portrait;



doc.PageSettings = pageSettings;






foreach (var kvp in RptTables)
{
PdfSection section = doc.Sections.Add(pageSettings);

section.Template.Top = new PdfPageTemplateElement(PdfPageSize.A4.Width - margins.Left - margins.Right, HeaderOffset);
section.Template.Bottom = new PdfPageTemplateElement(PdfPageSize.A4.Width - margins.Left - margins.Right, FooterOffset);


PdfSectionPageNumberField pn = new PdfSectionPageNumberField();
PdfSectionPageCountField pc = new PdfSectionPageCountField();
PdfCompositeField cf = new PdfCompositeField();
cf.AutomaticFields = new PdfAutomaticField[] { pn, pc };
cf.Text = "Page {0} of {1}";
cf.Font = FooterFont;
cf.Brush = FooterBrush;
cf.Location = new PointF(section.Template.Bottom.Width - margins.Right, FooterBuffer);
cf.StringFormat = FooterFmtRight;
cf.Draw(section.Template.Bottom.Graphics);

string Title = _config.Title;
if ((kvp.Key ?? "") != "")
{
section.Template.Bottom.Graphics.DrawString(kvp.Key, FooterFont, FooterBrush, 0, FooterBuffer, FooterFmtLeft);

Title += " - " + kvp.Key;
}


section.Template.Top.Graphics.DrawString(Title, HeaderFont, HeaderBrush, section.Template.Top.Width / 2, 0, HeaderFormat);



DrawPDFTable(section.Pages.Add(), kvp.Value);

}




#if DEBUG
int pgMax = 10;
while (doc.Pages.Count > pgMax)
doc.Pages.RemoveAt(doc.Pages.Count - 1);
#endif


MemoryStream Ret = new MemoryStream();
doc.SaveToStream(Ret, FileFormat.PDF);
return Ret;
}

jacobstx63
 
Posts: 4
Joined: Tue Jul 28, 2020 4:30 pm

Wed Jul 29, 2020 12:03 pm

Hello,

Thanks for your inquiry.
According to your code for further analysis, I found that the page number is not displayed completely because the x value of PdfCompositeField.Location you set is not appropriate. As shown below, by calculation, the width of the text "Page 10 of 10" is about 56, but the distance from x to the right margin of the page is 36, which is not enough to display the complete page number. So in your case, you need to set the value of X to a smaller value.
debug.png

Sincerely,
Rachel
E-iceblue support team
User avatar

rachel.lei
 
Posts: 1571
Joined: Tue Jul 09, 2019 2:22 am

Wed Jul 29, 2020 1:59 pm

Good morning and thanks for the reply.

Is there a way to have the field calculate the x value for each page separately or to right-align the field? I would like all pages to have the page number right aligned for all pages, and this solution would only work when the page number measures to 55.998.

jacobstx63
 
Posts: 4
Joined: Tue Jul 28, 2020 4:30 pm

Thu Jul 30, 2020 5:54 am

Hello,

Thanks for your response.
For this case, you can refer to the following code to calculate the value of X for each page. If there is any question, please feel free to write back.
Code: Select all
            //other code...
            //Set footer font
            PdfTrueTypeFont FooterFont = new PdfTrueTypeFont(new Font("Arial", 9f, FontStyle.Italic), true);
            //other code...

            //!!!*****************
            int pageNum = 1;
            int pageCount = RptTables.Count; //Maximum page number
            //!!!*****************

            foreach (var kvp in RptTables)
            {         
                PdfSection section = doc.Sections.Add(pageSettings);
                section.Template.Top = new PdfPageTemplateElement(PdfPageSize.A4.Width - margins.Left - margins.Right, HeaderOffset);
                section.Template.Bottom = new PdfPageTemplateElement(PdfPageSize.A4.Width - margins.Left - margins.Right, FooterOffset);
                PdfPageNumberField pn = new PdfPageNumberField();
                PdfPageCountField pc = new PdfPageCountField();
                PdfCompositeField cf = new PdfCompositeField();
                cf.AutomaticFields = new PdfAutomaticField[] { pn, pc };
                cf.Text = "Page {0} of {1}";
                cf.Font = FooterFont;
                cf.Brush = FooterBrush;

                //!!!*****************
                //Dynamically calculate the width of the current footer text
                float textWidth = FooterFont.MeasureString("Page " + pageNum + " of "+ pageCount).Width;
                float x = section.Template.Bottom.Width - textWidth;
                cf.Location = new PointF(x, FooterBuffer);
                cf.StringFormat = FooterFmtRight;
                cf.Draw(section.Template.Bottom.Graphics);

                pageNum++;
                //!!!*****************
                //other code...


Sincerely,
Rachel
E-iceblue support team
User avatar

rachel.lei
 
Posts: 1571
Joined: Tue Jul 09, 2019 2:22 am

Thu Jul 30, 2020 2:06 pm

Hi Rachel,

Thanks for the response.

This is measuring off of the table count, not the page count. Some of our tables span more than 10 pages, so we’ll run into the same issues since the composite field is drawn to the right of the same x position for each page in each template.

Alternatively, if there were a way to prevent the bottom of the table from drawing all the way to the margin on pages 2+, a way to draw in the margin without a template, or a way to specify that each page created by drawing the table should be created in a new section each, then I can add the page numbers manually.

jacobstx63
 
Posts: 4
Joined: Tue Jul 28, 2020 4:30 pm

Fri Jul 31, 2020 8:04 am

Hello,

Thanks for your feedback.
After further investigation, I found that if you want the StringFormat property to take effect, you need to specify both Location and Size property of PdfCompositeField, as shown below. Please give it a try on your side. Looking forward to your further feedback.
Code: Select all
        //...
        section.Template.Bottom = new PdfPageTemplateElement(PdfPageSize.A4.Width - margins.Left - margins.Right, FooterOffset);
        PdfPageNumberField pn = new PdfPageNumberField();
        PdfPageCountField pc = new PdfPageCountField();
        PdfCompositeField cf = new PdfCompositeField();
        cf.AutomaticFields = new PdfAutomaticField[] { pn, pc };
        cf.Text = "Page {0} of {1}";
        cf.Font = FooterFont;
        cf.Brush = FooterBrush;

        /****************!!!****************/
        //Method 1
        cf.Location = new PointF(0, FooterBuffer);
        cf.Size = section.Template.Bottom.Size;

        //Method 2
        //cf.Bounds = new RectangleF(new PointF(0, FooterBuffer), section.Template.Bottom.Size);               
        cf.StringFormat = new PdfStringFormat(PdfTextAlignment.Right);
        /****************!!!****************/
        cf.Draw(section.Template.Bottom.Graphics);
        //...


Sincerely,
Rachel
E-iceblue support team
User avatar

rachel.lei
 
Posts: 1571
Joined: Tue Jul 09, 2019 2:22 am

Fri Jul 31, 2020 3:23 pm

That did the trick. Thank you so much!

jacobstx63
 
Posts: 4
Joined: Tue Jul 28, 2020 4:30 pm

Mon Aug 03, 2020 1:44 am

Hello,

Glad to hear that!
If you encounter any issues related our product in the future, just feel free to contact us.
Have a nice day!

Sincerely,
Rachel
E-iceblue support team
User avatar

rachel.lei
 
Posts: 1571
Joined: Tue Jul 09, 2019 2:22 am

Return to Spire.PDF