在客户端(Flex)一侧需要一些简单的类。首先需要一个 ActionScript 类,该类将生成的 XDP 发送到服务器,并打开浏览器页来显示进入的 PDF。
import flash.net.*;
import flash.utils.ByteArray;
public class FormRenderer
{
public static function openPdf(xdp:String,
target:String="_blank"):void
{
var req:URLRequest = new URLRequest("/createPDF.jsp"); req.method = URLRequestMethod.POST;
var ba :ByteArray = new ByteArray();;
ba.writeMultiByte(xdp, "iso-8859-1");
ba.compress();
ba.position = 0;
req.data = ba;
navigateToURL(req, target);
}
}
}
现在我们需要的只是一个具有数据和显示的 XDP 文件。虽然让一个 XDP 文件可编程是可行的,但我们一般建议首先在(随 Acrobat Professional 提供的)LiveCycle Designer 中创建空模板,该模板匹配打印机的 paper size/corporate stationary。XDP 文档是 XML 对象,EcmaScript for XML (e4x) 使Flex中的 XDP 构建过程非常容易。例如:
1. 声明一个 XML 类型的变量,并使用 e4x 语法读取匹配文档和页面大小的 XDP 模板。下面是一个 XDP 模板的片段:
<?xfa generator="AdobeLiveCycleDesigner_V8.0" APIVersion="2.5.6290.0"?>
<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2007-01-25T10:40:38Z" uuid="784f469b-2fd0-4555-a905-6a2d173d0ee1">
<template xmlns="http://www.xfa.org/schema/xfa-template/2.5/">
<subform name="form1" layout="tb" restoreState="auto" locale="en_US">
<pageSet>
<pageArea name="Page1" id="Page1">
<contentArea x="0.25in" y="0.25in" w="8in" h="10.5in"/>
<medium stock="letter" short="8.5in" long="11in"/>
<?templateDesigner expand 1?></pageArea>
<?templateDesigner expand 1?></pageSet>
<subform w="8in" h="10.5in" name="YourPageAttachedHere"/>
<proto/>
<desc>
<text name="version">8.0.1291.1.339988.308172</text>
</desc>
</subform>
</template>
…
2. 选择一个要打印的 Flex 容器或控件,例如 Panel、DataGrid 等。
3. 从第 2 步查找该对象,获得其属性和子项,并创建准备此对象以便进行打印的 XML。将该 XML 作为一个页面附加到模板。如果您拥有自己的显示框架,所有组件可以实现您自己的界面(以下代码显示了只有一个 gette r 函数 xmlContent 的 IXdpContent ),该界面允许遍历屏幕上 XDP 内容的元素列表。您也可以拥有一个提供标准类的 XML 的处理器。下面是一般 DataGridItemRenderer 的实现,说明了如何准备打印一个 datagrid 单元:
package printing
{
import com.theriabook.controls.superGridClasses.DataGridItemRenderer;
public class DataGridItemRendererXdp extends DataGridItemRenderer
implements IXdpElement
{
public function get xmlContent():Object
{
var o:XML = <draw x={convert(x)} w={convert(width)}
h={convert(height)}>
<ui>
<textEdit>
</textEdit>
</ui>
<value><text>{text}</text></value>
<font typeface={getStyle("fontFamily")}
size={(getStyle("fontSize")*4/5)+"pt"}
weight={getStyle("fontWeight")}
posture={getStyle("fontStyle")}
underline={getStyle("textDecoration")=="normal"?1:0}
>
<fill>
<color value={rgb(getStyle("color"))}/>
</fill>
</font>
<margin topInset="0.5mm" bottomInset="0.5mm" leftInset="0.5mm" rightInset="0.5mm"/>
<border>
<edge presence="hidden"/>
<edge presence="visible"/>
<edge presence="hidden"/>
<edge presence="hidden"/>
</border>
</draw>;
return o;
}
private function convert(val:Number) : String {
return val/96 + "in"; //convert 96 dpi to inches
}
private function rgb(val:Number) : String {
return (val >> 16 & 255) + "," + (val >> 8 & 255) + "," + (val & 255);
}
}
}
4. 重复使用 E4X 将 XML 附加到 XDP 模板的过程,直到所有打印页就绪。
在我看来,这种从 Flex 打印的方法需要更少的报告努力。它还可能提供更好的打印质量,并且更易于在打印文档中搜索。