使用XSL样式表从XML生成PDF(HTML输出)时显示页码的咨询
Got it, let's tackle how to add page numbers to the top of each PDF page when generating from your XML with XSL-FO. Since you already have a ReportHeader variable and are handling pagination for 40 rows per page, here's how to integrate the page numbering seamlessly:
1. Ensure your page layout defines a header region
First, confirm your XSL-FO root has a page master that explicitly sets up a header area (this is where your ReportHeader and page numbers will live):
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="main-page" page-height="29.7cm" page-width="21cm" margin="2cm"> <!-- Define header area (adjust extent to match your header height) --> <fo:region-before extent="2.5cm" region-name="page-header"/> <!-- Main content area (leave space for header/footer) --> <fo:region-body margin-top="3cm" margin-bottom="2cm"/> <!-- Footer area if you already have one --> <fo:region-after extent="1.5cm" region-name="page-footer"/> </fo:simple-page-master> </fo:layout-master-set>
2. Inject your ReportHeader + page numbers into static header content
In your page sequence, use <fo:static-content> to define content that repeats on every page. Here, you'll reference your existing $ReportHeader variable and add the page number elements:
<fo:page-sequence master-reference="main-page"> <!-- Repeating header content --> <fo:static-content flow-name="page-header"> <!-- Insert your existing ReportHeader table --> <xsl:copy-of select="$ReportHeader"/> <!-- Add page numbering (adjust positioning based on your layout) --> <fo:block text-align="right" font-size="10pt" font-weight="bold" margin-top="0.5cm"> Page <fo:page-number/> of <fo:page-count/> </fo:block> </fo:static-content> <!-- Your existing footer static content (if applicable) --> <fo:static-content flow-name="page-footer"> <!-- Your footer content here --> </fo:static-content> <!-- Main content flow with your 100-row table --> <fo:flow flow-name="xsl-region-body"> <fo:table table-layout="fixed" width="100%"> <!-- Optional: Repeat table header on every page --> <fo:table-header table-omit-header-at-break="false"> <fo:table-row> <!-- Your table header cells here --> </fo:table-row> </fo:table-header> <fo:table-body> <!-- If you need to enforce exactly 40 rows per page, use grouping --> <xsl:for-each-group select="your-data-node-path" group-by="(position() - 1) idiv 40"> <xsl:for-each select="current-group()"> <fo:table-row> <!-- Your table data cells here --> </fo:table-row> </xsl:for-each> <!-- Add page break after each group except the last --> <xsl:if test="position() != last()"> <fo:block break-after="page"/> </xsl:if> </xsl:for-each-group> </fo:table-body> </fo:table> </fo:flow> </fo:page-sequence> </fo:root>
Key Details to Note:
<fo:page-number>: Outputs the current page number, automatically handled by your XSL-FO processor (like Apache FOP or RenderX XEP).<fo:page-count>: Outputs the total number of pages in the document—most modern processors support this, but double-check your tool if it doesn't work.- Positioning the Page Number: If you want the number inside your
ReportHeadertable (e.g., in a right-aligned cell), modify the table in your$ReportHeadervariable to include a cell that holds the<fo:page-number/>element instead of adding a separate block. - Enforcing 40 Rows Per Page: The
xsl:for-each-grouplogic groups your data into chunks of 40 rows and adds page breaks between groups, ensuring strict pagination. If your processor already handles auto-pagination correctly for your table height, you might not need this grouping.
Just plug this into your existing XSLT, adjust the paths to your data nodes and layout dimensions, and you should see page numbers at the top of every PDF page alongside your header.
内容的提问来源于stack exchange,提问作者Karthikeyan

