Parcourir la source

解决单个部分有多个Section时,元素重叠的问题

sunyj il y a 8 ans
Parent
commit
5439fad696
1 fichiers modifiés avec 71 ajouts et 26 suppressions
  1. 71 26
      src/main/resources/crystal2jasper.xsl

+ 71 - 26
src/main/resources/crystal2jasper.xsl

@@ -144,9 +144,12 @@
 						<band>
 							<xsl:attribute name="height"><xsl:value-of
 								select="round(sum(Area[@type='GroupHeader']/Section/@height) div $positionRate)" /></xsl:attribute>
-							<xsl:for-each select="Area[@type='GroupHeader']/Section/Element">
-							<xsl:call-template name="element">
-							</xsl:call-template>
+							<xsl:for-each select="Area[@type='GroupHeader']/Section">
+								<xsl:variable name="sectionPosition" select="position()" />
+								<xsl:call-template name="sections">
+									<xsl:with-param name="sectionPosition" select="$sectionPosition" />
+									<xsl:with-param name="previousSectionsHeight" >0</xsl:with-param>
+								</xsl:call-template>
 							</xsl:for-each>
 						</band>
 					</groupHeader>
@@ -154,9 +157,12 @@
 						<band>
 							<xsl:attribute name="height"><xsl:value-of
 								select="round(sum(Area[@type='GroupFooter']/Section/@height) div $positionRate)" /></xsl:attribute>
-							<xsl:for-each select="Area[@type='GroupFooter']/Section/Element">
-							<xsl:call-template name="element">
-							</xsl:call-template>
+							<xsl:for-each select="Area[@type='GroupFooter']/Section">
+								<xsl:variable name="sectionPosition" select="position()" />
+								<xsl:call-template name="sections">
+									<xsl:with-param name="sectionPosition" select="$sectionPosition" />
+									<xsl:with-param name="previousSectionsHeight" >0</xsl:with-param>
+								</xsl:call-template>
 							</xsl:for-each>
 						</band>
 					</groupFooter>
@@ -168,10 +174,12 @@
 				<title>
 					<band splitType="Stretch">
 						<xsl:attribute name="height"><xsl:value-of
-							select="round(AreaPair[@type='ReportAreaPair']/Area[@type='ReportHeader']/Section/@height div $positionRate)" /></xsl:attribute>
-						<xsl:for-each
-							select="AreaPair[@type='ReportAreaPair']/Area[@type='ReportHeader']/Section/Element">
-							<xsl:call-template name="element">
+							select="round(sum(AreaPair[@type='ReportAreaPair']/Area[@type='ReportHeader']/Section/@height) div $positionRate)" /></xsl:attribute>
+						<xsl:for-each select="AreaPair[@type='ReportAreaPair']/Area[@type='ReportHeader']/Section">
+							<xsl:variable name="sectionPosition" select="position()" />
+							<xsl:call-template name="sections">
+								<xsl:with-param name="sectionPosition" select="$sectionPosition" />
+								<xsl:with-param name="previousSectionsHeight" >0</xsl:with-param>
 							</xsl:call-template>
 						</xsl:for-each>
 					</band>
@@ -183,9 +191,11 @@
 					<band splitType="Stretch">
 						<xsl:attribute name="height"><xsl:value-of
 							select="round(sum(AreaPair[@type='PageAreaPair']/Area[@type='PageHeader']/Section/@height) div $positionRate)" /></xsl:attribute>
-						<xsl:for-each
-							select="AreaPair[@type='PageAreaPair']/Area[@type='PageHeader']/Section/Element">
-							<xsl:call-template name="element">
+						<xsl:for-each select="AreaPair[@type='PageAreaPair']/Area[@type='PageHeader']/Section">
+							<xsl:variable name="sectionPosition" select="position()" />
+							<xsl:call-template name="sections">
+								<xsl:with-param name="sectionPosition" select="$sectionPosition" />
+								<xsl:with-param name="previousSectionsHeight" >0</xsl:with-param>
 							</xsl:call-template>
 						</xsl:for-each>
 					</band>
@@ -196,10 +206,12 @@
 				<detail>
 					<band splitType="Prevent">
 						<xsl:attribute name="height"><xsl:value-of
-							select="round(AreaPair[@type='DetailArea']/Area[@type='Detail']/Section/@height div $positionRate)" /></xsl:attribute>
-						<xsl:for-each
-							select="AreaPair[@type='DetailArea']/Area[@type='Detail']/Section/Element">
-							<xsl:call-template name="element">
+							select="round(sum(AreaPair[@type='DetailArea']/Area[@type='Detail']/Section/@height) div $positionRate)" /></xsl:attribute>
+						<xsl:for-each select="AreaPair[@type='DetailArea']/Area[@type='Detail']/Section">
+							<xsl:variable name="sectionPosition" select="position()" />
+							<xsl:call-template name="sections">
+								<xsl:with-param name="sectionPosition" select="$sectionPosition" />
+								<xsl:with-param name="previousSectionsHeight" >0</xsl:with-param>
 							</xsl:call-template>
 						</xsl:for-each>
 					</band>
@@ -211,10 +223,12 @@
 				<pageFooter>
 					<band splitType="Prevent">
 						<xsl:attribute name="height"><xsl:value-of
-							select="round(AreaPair[@type='PageAreaPair']/Area[@type='PageFooter']/Section/@height div $positionRate)" /></xsl:attribute>
-						<xsl:for-each
-							select="AreaPair[@type='PageAreaPair']/Area[@type='PageFooter']/Section/Element">
-							<xsl:call-template name="element">
+							select="round(sum(AreaPair[@type='PageAreaPair']/Area[@type='PageFooter']/Section/@height) div $positionRate)" /></xsl:attribute>
+						<xsl:for-each select="AreaPair[@type='PageAreaPair']/Area[@type='PageFooter']/Section">
+							<xsl:variable name="sectionPosition" select="position()" />
+							<xsl:call-template name="sections">
+								<xsl:with-param name="sectionPosition" select="$sectionPosition" />
+								<xsl:with-param name="previousSectionsHeight" >0</xsl:with-param>
 							</xsl:call-template>
 						</xsl:for-each>
 					</band>
@@ -226,10 +240,12 @@
 				<lastPageFooter>
 					<band splitType="Prevent">
 						<xsl:attribute name="height"><xsl:value-of
-							select="round(AreaPair[@type='ReportAreaPair']/Area[@type='ReportFooter']/Section/@height div $positionRate)" /></xsl:attribute>
-						<xsl:for-each
-							select="AreaPair[@type='ReportAreaPair']/Area[@type='ReportFooter']/Section/Element">
-							<xsl:call-template name="element">
+							select="round(sum(AreaPair[@type='ReportAreaPair']/Area[@type='ReportFooter']/Section/@height) div $positionRate)" /></xsl:attribute>
+						<xsl:for-each select="AreaPair[@type='ReportAreaPair']/Area[@type='ReportFooter']/Section">
+							<xsl:variable name="sectionPosition" select="position()" />
+							<xsl:call-template name="sections">
+								<xsl:with-param name="sectionPosition" select="$sectionPosition" />
+								<xsl:with-param name="previousSectionsHeight" >0</xsl:with-param>
 							</xsl:call-template>
 						</xsl:for-each>
 					</band>
@@ -238,8 +254,32 @@
 		</jasperReport>
 	</xsl:template>
 
+	<!-- multi sections -->
+	<xsl:template name="sections">
+		<xsl:param name="sectionPosition" />
+		<xsl:param name="previousSectionsHeight" />
+		<xsl:choose>
+			<!-- if contains more than one section, then calculate the height of previous sections recursively -->
+			<xsl:when test="$sectionPosition > 1">
+				<xsl:call-template name="sections">
+					<xsl:with-param name="sectionPosition" select="$sectionPosition - 1" />
+					<xsl:with-param name="previousSectionsHeight" select="$previousSectionsHeight + ../Section[$sectionPosition - 1]/@height" />
+				</xsl:call-template>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:for-each select="Element">
+					<xsl:call-template name="element">
+						<xsl:with-param name="previousSectionsHeight" select="$previousSectionsHeight" />
+					</xsl:call-template>
+				</xsl:for-each>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+
 	<!-- process element -->
 	<xsl:template name="element">
+		<!-- height of previous sections -->
+		<xsl:param name="previousSectionsHeight" />
 		<xsl:variable name="type" select="@type" />
 		<xsl:choose>
 			<xsl:when test="$type='Box'"></xsl:when>
@@ -251,6 +291,7 @@
 						<!-- position -->
 						<xsl:call-template name="position" >
 							<xsl:with-param name="heightFactor">1.25</xsl:with-param>
+							<xsl:with-param name="previousSectionsHeight" select="$previousSectionsHeight" />
 						</xsl:call-template>
 						<!-- color -->
 						<xsl:variable name="foreColor"
@@ -331,6 +372,7 @@
 						<!-- position -->
 						<xsl:call-template name="position" >
 							<xsl:with-param name="heightFactor">1.25</xsl:with-param>
+							<xsl:with-param name="previousSectionsHeight" select="$previousSectionsHeight" />
 						</xsl:call-template>
 						<!-- color -->
 						<xsl:variable name="foreColor"
@@ -430,6 +472,7 @@
 						<!-- position -->
 						<xsl:call-template name="position">
 							<xsl:with-param name="heightFactor">1</xsl:with-param>
+							<xsl:with-param name="previousSectionsHeight" select="$previousSectionsHeight" />
 						</xsl:call-template>
 					</reportElement>
 					<imageExpression>
@@ -446,6 +489,7 @@
 						<!-- position -->
 						<xsl:call-template name="position">
 							<xsl:with-param name="heightFactor">1</xsl:with-param>
+							<xsl:with-param name="previousSectionsHeight" select="$previousSectionsHeight" />
 						</xsl:call-template>
 					</reportElement>
 					<!-- subreportParameter -->
@@ -487,11 +531,12 @@
 	<!-- position -->
 	<xsl:template name="position">
 		<xsl:param name="heightFactor" />
+		<xsl:param name="previousSectionsHeight" />
 		<xsl:attribute name="x">
 			<xsl:value-of select="round(@x_position div $positionRate)" />
 		</xsl:attribute>
 		<xsl:attribute name="y">
-			<xsl:value-of select="round(@y_position div $positionRate)" />
+			<xsl:value-of select="round((@y_position + $previousSectionsHeight) div $positionRate)" />
 		</xsl:attribute>
 		<xsl:attribute name="width">
 			<xsl:value-of select="round(@width div $positionRate)" />