XSL-FO is an XML language designed for describing all visual aspects of pagination documents.
The well known HTML is another language for specifying formatting semantics, but is more usable for documents that are presented to screen, and less for materials created for printing, because it doesn't support pagination elements like headers and footers, page size specifications, footnotes, etc.
XSL-FO is part of XSL language family:
XSLT - (XSL Transformations) a language for transfoming XML. (转换XML到XSL-FO)
XSL-FO - (XSL Formatting Objects) a language that can be used in XSLT for the purpose of "presenting" the XML. (XSL-FO使用fop可以直接转换为PDF)
XML + XSL Template ---> XSL Transformation ---> XSL-FO ---> FOP ---> PDF
The XSL-FO language uses CSS(Cascading Style Sheets) to describe formatting attributes like fonts, colors, and borders, fo from this point of view, it should be easy to learn by HTML developers.This Manual
will help you understand the language and accomplish more complicated tasks.
Here is the traditional Hello World, XSL-FO style:
<?xml version="1.0" encoding="UTF-8"?> <!-- 引入dtd,提供提示功能 --> <!DOCTYPE xsl-fo SYSTEM "fo.dtd"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="LetterPage" page-width="6.5in" page-height="2in"> <fo:region-body region-name="PageBody" margin="0.2in"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="LetterPage"> <fo:flow flow-name="PageBody" font-family="Microsoft YaHei" font-size="24pt"> <fo:block>Hello XSL-FO!</fo:block> </fo:flow> </fo:page-sequence> </fo:root>
(2) The pages structure is defined using fo:layout-master-set;
(3) The "Hello World" paragraph is added into this page.
- Horizontal alignment is controlled by text-align attribute.
- Borders are set using borders attribute.
- Font is using font-family, font-size, font-weight, etc.
- Spacing between two adjacent paragraph is set using space-before and space-after.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE fo SYSTEM "fo.dtd"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="LetterPage" page-width="5in" page-height="2in"> <fo:region-body region-name="PageBody" margin="0.2in"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="LetterPage"> <fo:flow flow-name="PageBody" font-family="Microsoft YaHei" font-size="10pt"> <fo:block text-align="justify" border="3pt solid green"> This is the first paragraph of justified text. Notice how text fills all available space for all lines except the last one.The alignment of the last line is controlled by text-align-last property. </fo:block> <fo:block space-before="1cm" border="3pt ridge blue"> This is the second paragraph. This block is left aligned. </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
justify: 对齐
text-align="justify" : 自动调整每行(除了最后1行)的文字间距,填满整行,看起来更美观。
text-align-last="justify" : 调整最后1行文字,让其填充满整行
There are several things to notice:
(1) The distance between paragraphs is not additive(没有叠加性)
(2) If a block is the first element in a page, and you set the space-before attribute, you will also notice that the space is not present anymoe!
This behavior is controlled by space-before.conditionality. If you set to "retain"(保留), the corresponding space will not be discarded(丢弃).
If a block is the last element in a page, and you set the space-after attribute, you will also notice that the space is not present anymore!
This behavior is controlled by space-before.conditionality. If you set to "retain"(保留), the corresponding space will not be discarded(丢弃).
Text Alignment
Horizontal alignment of text is controlled by two attributes: text-align which will set the alignment for all lines of text, except the last one, which is controlled by text-algin-last.
This is important to remenber, because if your paragraph has only one line of text, you
have to use text-align-last to set the alignment !
Possible values for text-align and text-align-last are:
left (the default) to perform alignment to the left
right, to perform alignment to the right
center, to center the paragraph
justify, to justify the text, so that if fills the while line
Vertical alignment of text is controlled by display-align attibute. This attribute can have the
following values:
auto (the default)
before
center
after
Fonts
There are six properties that can control the aspect of text:
font-family, font-style, font-variant, font-weigth, font-size, line-height
font-family
To set the font face, you use font-family attribute. For example, font-family="Arial" will
specify that Arial font must be used.
If multiple font family are specified, the render will pick the first avaiable, so you should
list the fonts from the most specific to the most generic.
For example, font-family="Arial, Helvetica" will select "Helvetica" if "Arial" is not present in the system.
font-weigth
The weight of the font can be specified using font-weight attribute.
You can set it to either an absoulte value("bold" or "normal"), or to a value relative to parent element's font weight("bolder" or "lighter").
font-size
To specify the font size, use font-size attribute.
This size can be a length(1cm, 0.5in, 10pt, 8px, etc) or a percentage(0.5, 150%) from parent element's font.
line-height
A very important, and often misused property is line-height. This property determines the
minimun line-height for a block element. The default value for line-height is 120%, that is,
the line will be 20% taller than the text.
For example, if the text is 10 ponits height, the line height will be of 12 points.
The text will be centered on the line, 1 point from top, and 1 point from bottom.
In the next example we set the line-height to 200% :
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE fo SYSTEM "fo.dtd"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="LetterPage" page-width="5in" page-height="1.5in"> <fo:region-body region-name="PageBody" margin="0.2in"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="LetterPage"> <fo:flow flow-name="PageBody" font-family="Microsoft YaHei" font-size="10pt"> <fo:block line-height="200%" border="3pt outset blue" padding="5pt"> For this paragraph, the line-height is set to 200%. Because the font is 12 points height, an extra 12 points will be seperate 6pt to top, 6pt to bottom. </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
We have mentioned before that is the minimun line height: if a line contains an image of
let's say 100 points height, the total line height (only for that line) will be of 102 points
(%2 extra) .
To set all the properties at once you can use font shortcut attribute.
A shortcut attribute will set the values for multiple attributes at once.
The shortcut attribute font has the following syntax:
font="{style} {variant} {weight} {size}/{line-height} family"
For example, to achieve the same effect as the first example in this chapter, you could
use font="10pt Arial", font=""
Note: By using this shortcut attribute, instead of specifying each font properity individually,
child shortcut will inherit the parent setting!
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE fo SYSTEM "fo.dtd"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="LetterPage" page-width="5in" page-height="1.5in"> <fo:region-body region-name="PageBody" margin="0.2in"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="LetterPage"> <fo:flow flow-name="PageBody"> <fo:block font-size="12pt" font-weight="bold" font-family="Microsoft YaHei"> <fo:block> This is the parent block element with a 12 points, bold, "Microsoft YaHei" </fo:block> <fo:block font="12pt Arial"> This is the child block element; the same shortcut is used for changing the font, but because the weight was omitted, the font is no longer bold. </fo:block> <fo:block> When the child block ends, the remaining of parent's content is displayed! </fo:block> </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
Border
The border properties specify the width, color, and style of the borders a object.
These properties applay to all XSL-FO elments.
Border widths are set using border-top-width,border-right-width,border-bottom-width,border-left-width.
The value can be specified as a length(1pt, 0.5cm, etc). To set all four widths at once you can use border-width shortcut. For example, to set all borders to 0.1 inches thick, you use border-width="0.1in".
Border color properties are border-top-color, border-right-color, border-bottom-color, border-left-color,
The shortcut for setting the color for all four borders at once is border-color.
The border style properties specified the line style of a box's border(solid, double, dashed, etc).
The properties defined in this section refer to the border-style value type, which may take one of the following:
none or hidden : No border
dotted: The border is a series of dots.
dashed: The border is a series of short line segments.
solid: The border is a single line segement.
double: The border is two solid lines.The sum of the two lines and the space between them equals the vaule of "border width".
groove(凹槽 ): The border looks as though it were carved(雕刻) into the canvas.
ridge(凸出): The opposite of "groove":the border looks as though it were coming out of the canvas.
inset(嵌入): The border makes the entire box looks as though it were embedded in the canvas.
outset: The opposite of "inset": the border makes the entire box looks as though it were coming out of the canvas.
All borders are drawn on top of the background.
To set all attributes for a given border, you can use border-top, border-right, border-bottom, border-left shorthand attributes.
The format is:
border-top="{width} {style} {color}"
The following notations are equivent:
<fo:block border-top-style="solid" border-top-color="blue" border-top-width="1mm">
...
</fo:block>
<fo:block border-top="1mm solid blue">
...
</fo:block>
The border property is a shorthand property for setting the same width,color, and style for all four borders of a box.The border property cann't set different values on the four borders.To do so, one or more of the other border properties must be used.
The format is:
border="{width} {style} {color}"
border="3pt solid red"
Backgrounds
XSL-FO object's background may be colors or images.
Background properties allow authos to position a background image, repeate it, etc.
To set the background color of an element use background-color attibute.
It can be set to either a color value or the keyword "transparent".
background-image sets the background image of an element.
When setting a background image, authos should also specify a background-color that will be used when the image is unavailable.When the images is available, it is rendered on top of the background color.(Thus, the color is visble in the transparent parts of the image). Values for this property are either URL, to specify the image, or "none", when no image is used.
If a background image is used, background-repeat attributes specifies whether the image is repeated(tiled 平铺), and how.
It may take one of the following values:
repeat: The image is repeated both horizontally and vertically.
repeat-x: The image is repeated horizontally only.
repeat-y:The image is repeated vertically only.
no-repeat:The image is not repeated: only one copy of the image is drawn.
If a background image has been specified, background-position property specifies it's initial position.
Values have the following meanings:
percentage percentage: With a value pair of "0% 0%", the upper left corner of the image is aligned with the upper left corner of the box's padding edge. A value pair of "100% 100%" places the lower right corner of the image in the lower right corner of padding area. With a value pair of "14% 86%", the point 14% across and 86% down the images is to be placed at the point 14% accross and 86% down the padding area.
length length: With a value pair of "2cm 2cm", the upper left corner of the image is places 2cm to the left and 2cm below the upper left corner of the padding area.(图片距离左边水平距离2cm,垂直距离2cm)
If only one percentage or length value is given, it sets the horizontal position only, the vertival position will be 50%.
If two values are given, the horizontal position comes first.
Combinations of length and percentage values are allowed(e.g., "50% 2cm").
Negative positions are allowed.
To set all attributes for one element's background, you can use background shortcut attribute.
The format is:
background="{color} {image} {repeat} {position}"
<fo:block th:attr="background-image=${firstPagePicLinkerPDF}" th:fragment="bg-sample-1" background-position="0,0" background-repeat="repeat" background-color="white" font-size="10pt">
Only part of the image presented, because size of the text occupation in the block isn't big than the image size.
So, how big the bolck present is equal to the images present!
<Flow Layout>
XSL-FO documents have flow layout, that is, content "flows" from one page to the next one:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Project> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="LetterPage" page-width="6in" page-height="2in"> <fo:region-body region-name="PageBody" margin="0.1in" background-color="rgb(245,245,245)"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="LetterPage"> <fo:flow flow-name="PageBody" font-size="12pt"> <fo:block border="2pt solid black" space-after="5pt" text-align="justify"> The content of this block is split across multiple pages. The content of this block is split ........ .................................................. The content of this block is split across multiple pages. </fo:block> <fo:block border="2pt solid red" keep-together="always"> This block has <fo:inline text-decoration="underline">keep-together</fo:inline> set to always. Because of this flag, the block will be displayed on a new page as the render tries to prevent the block from spliting. </fo:block> <fo:block border="2pt solid rgb(255,0,255)" space-after="5pt" keep-with-next="always"> A block element that still fits on the previouse page. </fo:block> <fo:block border="2pt solid black"> A block on the last page. The previous page block will be displayed on the <fo:inline text-decoration="underline">same</fo:inline> page because it has keep-with-next flag set. </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
keep-together="always"
防止1个块中的内容被分割到不同页进行显示
但是,定义了该属性fop处理自动对内容进行了浮动,这里有问题。。。
keep-with-next="always"
定义了此属性的block,即使上一页的剩余空间足够显示该block,也不会在上一页中显示。而是与下一个块保持在1个页面,即会出现在下一页中
There are several properties that control how and when a block of text is split across multiple pages.(几种控制分页的方法)There are :
break-before and break-after attributes will force a page break before or after a block element. By block element we mean elements that fill all available horizontal space like paragraphs, tables, and lists. For example, you might want to use this to start chapters on a new page.
强制在某个block之前还是之后进行分页,如新的一章则需要新的一页
keep-together attribute prevents splitting of a block element, If there is not enough room to display the block on the current page, the block will be displayed on the next one.
如果当前页的空间不足以放下该block,则其将在下一页中进行显示,保证block内容在一个页面中显示。
keep-with-next and keep-with-previous will link a block element with the previous/next sibling block. This is useful to prevent page breaks occur between two closely related elements, like chapter title and chapter contents.
与下一个block建立关系
与上一个block建立此关系
防止关系亲密的2个block块分散到不同的page,因为它们需要在同一个page中显示。
widow and orphans attributes are useful to control contextual information. The default values for this properties is "2", preventing the display of last line of a paragraph by itselt at
the top of a page(a widow) or the first line of a paragraph by itself at the bottom of a page(an orphan). You can see in the example above the fo:block will display the two line on the second page.
防止1个段落的最后1行在下一个新页面中第1行的位置显示(寡妇)
防止1个段落的第1行在前一页的最后一行的位置显示(孤儿)
<Inline Text Formatting>
Inline Text Formatting
Inline elements allow XSL-FO developers to specify attributes for individual pieces of inline content(text and image), instead of the whole block.
In the example below, a fragment of text is filled with red, and it's font weight is set to bold:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Project> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="LetterPage" page-width="6in" page-height="2in"> <fo:region-body region-name="PageBody" margin="0.1in" background-color="rgb(245,245,245)"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="LetterPage"> <fo:flow flow-name="PageBody" font-size="12pt"> <fo:block font-size="14pt"> Some <fo:inline font-weight="bold" color="red">inline text</fo:inline> fomatting. </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
Things to notice:
(1) The fo:inline element wraps the fragment "inline text" and sets font-weight to bold. The text color is set to red using color attribute.
Any color can be described using either a standard color value or by using it's red, green and blue components. The following notations are equivalent:
<fo:inline color="red">Hello</fo:inline>
<fo:inline color="rgb(255,0,0)">Hello</fo:inline>
Subscripts and Superscripts
上标与下标
Inline elements also allow creation of sub-scripts or super-scripts:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Project> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="LetterPage" page-width="6in" page-height="2in"> <fo:region-body region-name="PageBody" margin="0.1in" background-color="rgb(245,245,245)"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="LetterPage"> <fo:flow flow-name="PageBody" font-size="12pt"> <fo:block font-size="14pt"> Some <fo:inline font-weight="bold" color="red" baseline-shift="sub">inline text</fo:inline> fomatting. Some <fo:inline font-weight="bold" color="red" baseline-shift="super">inline text</fo:inline> fomatting. </fo:block> <fo:block font-size="14pt"> Some <fo:inline font-weight="bold" color="red" baseline-shift="-50%">inline text</fo:inline> fomatting. Some <fo:inline font-weight="bold" color="red" baseline-shift="50%">inline text</fo:inline> fomatting. </fo:block> <fo:block font-size="14pt"> Some <fo:inline font-weight="bold" color="red" baseline-shift="-5pt">inline text</fo:inline> fomatting. Some <fo:inline font-weight="bold" color="red" baseline-shift="5pt">inline text</fo:inline> fomatting. </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
The property that controls the alignment of an inline element vertically within it's parent line
is baseline-shift.
As you can see in this example, the text can be shifted vertically using either "sub" or "super" which will use font metrics to determine the subscript or superscript positions.
You can also use a percentual or absolute value.
<Graphics>
SVG (Scalable Vector Graphics)
External Graphics
To display an image from an external file, use fo:external-graphic.
All majors formats are supported, like BMP,JPEG,GIF,PNG,etc.
<fo:external-graphic src="sample.jpg" content-height="0.7in" vertical-align="middle"/>
There are several things to notice in this example:
Image urls can be eigther absolute or relative. When relative, the location of the XSL-FO document is used to compute the full path to the image.
Image can be scaled using content-width and content-height properties.
In this example we specify only the desired height and the width is computed automatically by the render, preserving the aspect ratio.
Inline graphics can be shifted vertically using vertical-align attribute.
<fo:block margin-top="10px" margin-left="5px"> <fo:external-graphic content-width="scale-to-fit" content-height="scale-to-fit" width="6.8in" height="1.2in" src="./public/images/logo.jpg"/> </fo:block>
<Float>
fo:float element inserts an out-of-line(不在一直线上) block-level element such as a figure(图解) or a pull quote(醒目引文) onto the page.
The float property determines which side of the page it floats on and the clear property determines whether and where other elements are allowed to float around it.
float property 决定把目标浮动到页面的那一边,clear property决定是否允许其它元素浮动到其周围
【fop1.0, 1.1, 目前尚不支持fo:float功能!】
<Absolute Position>
When an object is placed on a page, it can be positioned absolute or relative.
页面中的某个对象,可以使用绝对或者相对定位来控制元素的位置
Most objects are relative, which means that if preceding(在前面的) objects grow/become larger, that the relative objects will shift (in most languages it shift down) .
大多数对象都是相对的,这就意味着如果前面的对象变大导致所使用的空间增大,相对该
对象的其它对象的位置将发生移动(大多数情况是向下移动)。
We have seen that XSL-FO documents have flow layout, the content flows from one page to the next one, according to the rules imposed(利用) by page breaks, spacing, widows and orphans.
XSL-FO中,可以对是否分页进行控制
However, sometimes it may be useful to position elements at absolute coordinates.
一些时候,使用绝对定位来控制元素的位置也是相当有用的
Only fo:block-container can be placed absolutely, and this can be done by setting the position properity to "absolute" or "fixed".
The value "fixed" means that the object has a position relative to the page.
position="fixed" 是相对与Page页面左上角进行定位的
The value "absolute" means that the object has a position relative to the containing reference-area,typically another fo:block-container. This containing reference-area does not need to be positioned absolutely, which means you can position an object on a sepecifc absolute location relative to another object that flows in the page.
position="absolute" 相对于其所在的上下文环境进行进行定位的,不一定是页面左上角
如,分栏中的第2栏出现absolute定位,则相对与第2栏进行定位
In the example below, we have two fragments of text positioned under and over the main flow text:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Project> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <!-- 页面样式一 --> <fo:simple-page-master master-name="p1" page-width="7in" page-height="2in"> <fo:region-body region-name="xsl-region-body" margin="0.5in"/> </fo:simple-page-master> <!-- 页面样式二 --> <fo:simple-page-master master-name="p2" page-width="7in" page-height="2in"> <!-- column-count Region分2栏显示内容 --> <fo:region-body region-name="xsl-region-body" margin="0.2in" column-count="2"/> </fo:simple-page-master> <fo:page-sequence-master master-name="default-sequence"> <!-- 第1页使用p1样式 --> <fo:single-page-master-reference master-reference="p1"/> <!-- 余下的使用p2样式 --> <fo:repeatable-page-master-reference master-reference="p2"/> </fo:page-sequence-master> </fo:layout-master-set> <fo:page-sequence master-reference="default-sequence"> <fo:flow flow-name="xsl-region-body" font-size="12pt"> <!-- 绝对定位 --> <fo:block-container position="absolute" top="10pt" left="30pt" height="14pt" width="100%"> <fo:block font-size="72pt" color="silver">Under</fo:block> </fo:block-container> <fo:block> <fo:block> Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text </fo:block> <!-- 绝对定位 --> <fo:block-container position="absolute" top="20pt" left="40pt" height="14pt" width="100%"> <fo:block font-size="72pt" color="red">Over</fo:block> </fo:block-container> </fo:block> <!-- 换页 --> <fo:block break-before="page"/> <!-- 绝对定位 --> <fo:block-container position="absolute" top="10pt" left="30pt" height="14pt" width="100%"> <fo:block font-size="72pt" color="silver">Under</fo:block> </fo:block-container> <fo:block> <fo:block> Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text </fo:block> <!-- 绝对定位 --> <fo:block-container position="absolute" top="10pt" left="30pt" height="14pt" width="100%"> <fo:block font-size="72pt" color="red">Over</fo:block> </fo:block-container> </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
To change the order in which the elements are rendered, use z-index attributes:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Project> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="p1" page-width="5in" page-height="7in"> <fo:region-body region-name="xsl-region-body" margin="0.5in"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="p1"> <fo:flow flow-name="xsl-region-body" font-size="12pt"> <!-- 绝对定位和z-index定位的文字,需要放在正文内容之前输出到页面 --> <!-- Negative z-index --> <fo:block-container z-index="-1" position="absolute" top="18pt" left="0pt"> <fo:block font-size="48pt" color="rgb(192,192,192)" text-align="center"> Under </fo:block> </fo:block-container> <!-- Positive z-index --> <fo:block-container z-index="+1" position="absolute" top="28pt" left="10pt"> <fo:block font-size="48pt" color="red" text-align="center"> Under </fo:block> </fo:block-container> <fo:block> Before Before Before Before Before Before Before Before Before Before Before Before Before Before Before Before Before Before </fo:block> <fo:block> After After After After After After After After After After After After After After After After After After After After After After After After </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
All elements are considered have a z-index of 0.
Therefore, if you want an element to be displayed on the background(like a watermark) use a Negative z-index, while for a foreground element (like a stamp) use a positive z-index.
z-index 小于0,文字可以作为背景,类似水印的效果。
z-index 大于0,文字可以作为覆盖层,类似邮戳效果。
<Tables>
Tables are described in XSL-FO using fo:table element.
A table can have a herder(fo:tableheader), a body(fo:table-body) and a footer(fo:table-footer).
Each of these groups contains rows(fo:table-row), which in turn contain cells(fo:cell)
The columns are described using fo:table-column elements.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Project> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="normal" page-height="297mm" page-width="210mm" margin-top="20mm" margin-bottom="20mm" margin-left="25mm" margin-right="25mm"> <fo:region-body margin-bottom="20mm"/> <fo:region-before extent="1cm"/> <fo:region-after extent="1cm"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="normal"> <fo:flow flow-name="xsl-region-body"> <fo:table table-layout="fixed" width="100%" border-collapse="collapse" font-size="12pt"> <!-- 声明列数,列宽按比例进行设置,对第1列设置背景颜色 --> <fo:table-column column-width="50%" background-color="rgb(255,246,206)"/> <fo:table-column column-width="25%"/> <fo:table-column column-width="25%"/> <fo:table-header color="rgb(255,255,255)" background-color="rgb(125,73,2)" font-weight="bold"> <fo:table-row> <fo:table-cell padding="2pt" border="1pt solid black"> <fo:block>Name</fo:block> </fo:table-cell> <fo:table-cell padding="2pt" border="1pt solid black"> <fo:block>Quantity</fo:block> </fo:table-cell> <fo:table-cell padding="2pt" border="1pt solid black"> <fo:block text-align="right">Price</fo:block> </fo:table-cell> </fo:table-row> </fo:table-header> <fo:table-body> <fo:table-row> <fo:table-cell padding="2pt" border="1pt solid black"> <fo:block>Product 1</fo:block> </fo:table-cell> <fo:table-cell padding="2pt" border="1pt solid black"> <fo:block>100</fo:block> </fo:table-cell> <fo:table-cell padding="2pt" border="1pt solid black" text-align="right"> <fo:block>$100.11</fo:block> </fo:table-cell> </fo:table-row> <fo:table-row> <fo:table-cell padding="2pt" border="1pt solid black"> <fo:block>Product 2</fo:block> </fo:table-cell> <fo:table-cell padding="2pt" border="1pt solid black"> <fo:block>Single</fo:block> </fo:table-cell> <fo:table-cell padding="2pt" border="1pt solid black" text-align="right"> <fo:block>$18.00</fo:block> </fo:table-cell> </fo:table-row> <fo:table-row> <fo:table-cell padding="2pt" border="1pt solid black"> <fo:block>Product 3</fo:block> </fo:table-cell> <fo:table-cell padding="2pt" border="1pt solid black"> <fo:block>Single</fo:block> </fo:table-cell> <fo:table-cell padding="2pt" border="1pt solid black" text-align="right"> <fo:block>$122.99</fo:block> </fo:table-cell> </fo:table-row> </fo:table-body> </fo:table> </fo:flow> </fo:page-sequence> </fo:root>
Things to notice:
1. The fo:table element is defined. This table has the border-collaspe attribute set to "collapse", which will cause borders to merge.
2. Columns can have eigther a fixed width or a percentage width.
3. We difine table's header and body. If a page break will occurs, the headers and the footers are displayed on the next page as well.
4. Each fo:table-cell can span multiple rows and/or columns.
5. Set table-layout="fixed" width="100%" to the table, otherwise fop will throw warning message.
The content of the cell is aligned vertically according to display-align property.
Note:
By default a cell will not clip it's content.To clip the cell's content set overflow attribute to hidden.
当文本内容超出单元格的大小时,通过设置overflow=“hidden”来隐藏溢出的文字
Table columns
As noted in the example above, a column can have a proportional(比例) width or a fixed width.
A fixed width includes length units(in, pt, cm,etc)
for example:
<!-- Fixed column width --> <fo:table-column column-width="3in"/> <!-- A proportional width is expressed via proportional-column-width --> <fo:table-column column-width="proportional-column-width(20)"/> <fo:table-column column-width="20%"/>
There is a third way to specify a column width:
By omitting the column-width attribute, the column will size itself automatically, dependding on it's content.
start-indent is an inheritable property, the block in the table-cell will also indent !
To indent only the table, you can eigth:
~ Use margin-left instead of start-indent
~ Use start-indent for the table, and then use it again for each table-cell, but set it's value to zero. (start-indent="0")
<Lists>
XSL-FO lists are created using fo:list-block element.
A list can contain one or more items: fo:list-item
Each item has a label: fo:list-item-label usually used to display a bullet or a number, and body: fo:list-item-body.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE fo SYSTEM "fo.dtd"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="normal" page-width="210mm" page-height="297mm"> <fo:region-body region-name="xsl-region-body"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="normal"> <fo:flow flow-name="xsl-region-body"> <fo:block> To do list: </fo:block> <fo:list-block> <fo:list-item> <fo:list-item-label end-indent="label-end()"> <fo:block>1)</fo:block> </fo:list-item-label> <fo:list-item-body start-indent="body-start()"> <fo:block> Very very important stuff </fo:block> </fo:list-item-body> </fo:list-item> <fo:list-item> <fo:list-item-label end-indent="label-end()"> <fo:block>2)</fo:block> </fo:list-item-label> <fo:list-item-body start-indent="body-start()"> <fo:block> Very important stuff </fo:block> </fo:list-item-body> </fo:list-item> <fo:list-item> <fo:list-item-label end-indent="label-end()"> <fo:block>3)</fo:block> </fo:list-item-label> <fo:list-item-body start-indent="body-start()"> <fo:block> Other important items </fo:block> </fo:list-item-body> </fo:list-item> <fo:list-item> <fo:list-item-label end-indent="label-end()"> <fo:block>4)</fo:block> </fo:list-item-label> <fo:list-item-body start-indent="body-start()"> <fo:block> Don't forget to eat </fo:block> </fo:list-item-body> </fo:list-item> <fo:list-item> <fo:list-item-label end-indent="label-end()"> <fo:block>5)</fo:block> </fo:list-item-label> <fo:list-item-body start-indent="body-start()"> <fo:block> Sleep would be good </fo:block> </fo:list-item-body> </fo:list-item> </fo:list-block> </fo:flow> </fo:page-sequence> </fo:root>
<Page>
Every page has the following regions:
- fo:region-body which holds the main page content, that is, the cotent of fo:flow
- fo:region-before used to diaplay headers
- fo:region-after userd to display footers
- fo:region-start used to display left regions
- fo:region-end used to display right regions
Of all regions, fo:region-body can have multiple columns:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE DTD SYSTEM "fo.dtd"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="all-pages" page-width="5in" page-height="5in"> <fo:region-body region-name = "Content" margin="0.7in" column-gap="0.25in" column-count="2" /> <fo:region-before region-name="Header" extent="0.7in" display-align="after" background-color="red" /> <fo:region-after region-name="Footer" extent="0.7in" display-align="before" background-color="blue" precedence="true" /> <fo:region-start region-name="LeftMargin" extent="0.7in" background-color="green" reference-orientation="90" display-align="after" /> <fo:region-end region-name="RightMargin" extent="0.7in" background-color="yellow" reference-orientation="-90" display-align="after" /> </fo:simple-page-master> <fo:page-sequence-master master-name="default-sequence"> <fo:repeatable-page-master-reference master-reference="all-pages" /> </fo:page-sequence-master> </fo:layout-master-set> <fo:page-sequence master-reference="default-sequence"> <fo:static-content flow-name="Header" font-family="Arial" font-size="10pt" color="white"> <fo:block> The header of the page is aligned on the bottom of fo:region-before. </fo:block> </fo:static-content> <fo:static-content flow-name="Footer" font-family="Arial" font-size="10pt" color="white"> <fo:block> The footer of the page is aligned on the top of fo:region-after. The footer has the "precedence" attribute set. </fo:block> </fo:static-content> <fo:static-content flow-name="LeftMargin" font-family="Arial" font-size="10pt" color="white"> <fo:block> This is the left margin of the page. The region is rotated 90 degrees, and the content is vertically aligned on the bottom. </fo:block> </fo:static-content> <fo:static-content flow-name="RightMargin" font-family="Arial" font-size="10pt"> <fo:block> This is the right margin of the page. The region is rotated -90 degrees, and the content is vertically aligned on the bottom. </fo:block> </fo:static-content> <fo:flow flow-name="Content" font-family="Microsoft YaHei" font-size="10pt" text-align="justify"> <fo:block> The body region's content flows in two columns. The body region's content flows in two columns. The body region's content flows in two columns. The body region's content flows in two columns. </fo:block> <fo:block span="all" border="1pt solid red" padding="2pt" space-before="3pt" space-after="3pt" start-indent="2pt" end-indent="2pt"> This block has "span" attribute set to all, which will make it span all the columns in the page. Note that span attribute can be set only for those blocks with a fo:flow as the direct parent. </fo:block> <fo:block> The body region's content flows in two columns. The body region's content flows in two columns. The body region's content flows in two columns. The body region's content flows in two columns. </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
<Page Numbers>
fo:page-number is used to insert the current page number.
fo:page-number-citation is used to retrieve the page number of a given element. This elment is also usefull in insert the number of pages in a document, as show below:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE DTD SYSTEM "fo.dtd"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="LetterPage" page-width="297mm" page-height="210mm" margin="0.2in"> <fo:region-body region-name="PageBody" /> <fo:region-after region-name="Footer" extent="0.2in" /> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="LetterPage" font="10pt Arial"> <!-- 使用static-content在foot中显示页码 --> <fo:static-content flow-name="Footer"> <!-- 定义1个上边框作为一条横线,与正文隔开,在其下方显示页码 --> <fo:block text-align="right" border-top="1pt solid black" padding-top="1mm"> Page <fo:page-number /> of <fo:page-number-citation ref-id ="the End" /> </fo:block> </fo:static-content> <fo:flow flow-name="PageBody"> <fo:block> The text content of the first page. </fo:block> <fo:block break-before="page"> The text content of the second page. </fo:block> <!-- 正文末尾处声明"引用" --> <fo:block id="the End" /> </fo:flow> </fo:page-sequence> </fo:root>
<分栏>
column-count
Specify the number of columns in the region.
Initial value: 1
A value of 1 indicates that this is not a multi-column region.
指定block中的内容将被分为几栏
column-gap 指定栏与栏之间的间隔(需与column-count结合使用才有意义)
Initial value: 12pt
<fo:region-body region-name="xsl-region-body" margin="0.1in" background-color="rgb(245,245,245)" column-count="2" column-gap="0.25in"/>
注意:当column-count>1的时候指定column-gap才有意义!