技术开发 频道

在servlet中使用jfreereport直接产生pdf文件报表

【IT168技术文档】

    首先说些废话。

    基于Java开发的Web的应用系统的打印问题一直困扰着我。原因是基于Web的应用是瘦客户端应用,逻辑集中在服务器上,而打印是基于客户端的行为。

    目前基于Web的精确打印解决方案主要有两类:一是加强客户端的逻辑;二是在服务器端产生适于精确打印的文件。
流行的打印工具中用Applet实现、用浏览器插件实现或是开发嵌入浏览器的客户端的方法属于第一类;而在服务器端产生图片文件、pdf或ps等

    精确打印文件的方法属于第二类。

    以上流行的解决方案的比较:

方案 打印效果 浏览器依赖 部署代价  维护代价
Applet实现 页面控制困难 需要java plug-in插件 无需客户端部署 客户端调整
浏览器插件实现 同本地打印 依赖特定类型版本的浏览器 客户端动态部署 客户端动态部署
图片文件实现 页面控制困难
df文件实现 同本地打印 需要acroreader插件 无需客户端部署


    pdf文件是流行的文件格式,浏览器和pdf阅读器已成为客户端必备的安装内容。对于通用的打印解决方案我认为pdf文件的方式具有更大的灵活性和可用性。

    废话到此为止,下面就给出一个servlet通过模板生成pdf文件的实现:

    我选择的是报表工具是jfreereport,当然若简单的文本可以使用iText直接产生。

    1. jfreereport与was5.0.x的集成

    was5.0.x依据j2ee 1.3规范,jaxp/dom/sax的版本分别为1.1/2/2,与jfreereport依赖的gunjaxp.jar中的一致,其他的包也不存在冲突。因此可以将这些

   包直接加到Web项目的包目录/WEB-INF/lib中。jfreereport的包很多,与读取模板、生成报表和生成pdf文件相关的有:
    gnujaxp.jar
    itext-1.2.2.jar
    iTextAsian.jar
    jcommon-0.9.7.jar
    jfreereport-0.8.4_11-core.jar
    jfreereport-0.8.4_11-misc-configstore-base.jar
    jfreereport-0.8.4_11-output-pageable-base.jar
    jfreereport-0.8.4_11-output-pageable-pdf.jar
    jfreereport-0.8.4_11-output-support-itext.jar
    jfreereport-0.8.4_11-output-support-pagelayout.jar
    jfreereport-0.8.4_11-parser-base.jar
    jfreereport-0.8.4_11-parser-ext.jar
    pixie-0.8.1.jar

j    freereport中自带的itext-1.02b.jar版本低,可以替换为新版本,iTextAsian.jar是生成中文所必须的。


    2. 编码和汉字问题

    由于我的环境是英文系统(Win2k en version + sp4)加装中文支持,为了在开发环境中支持中文必须使用UTF-8编码。因此需要对jfreereport中的一些参数进行配置。
需要将org\jfree\report\modules\output\support\itext\configuration.properties文件中的org.jfree.report.modules.output.support.itext.Encoding参数设为GBK (或GB18030,请量力而行,我的环境未安装GB18030的支持)。

    需要将显示中文的区域的字体和编码分别设为"STSong-Light"和"UniGB-UCS2-H"。此字体和编码是生成pdf文件时显示中文所必须的,与jfreereport的GUI工具的显示无关。

    3. 程序示例

    我选用了jfreereport中的Java Look and Feel Graphics Repository的例子,并将部分内容换为中文。以下是直接生成pdf的servlet代码和我变更的报表模板。

//- GenPDFByJfreereportTemplateServlet.javapackage acme.web.servlets;
//- swing-icons.xml <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE report-definition PUBLIC "-//JFreeReport//DTD report definition//EN//extended" "http://jfreereport.sourceforge.net/extreport.dtd"><!-- ***************************************************************** --><!-- * Swing-Icons.XML * --><!-- * A sample report definition used as an introduction to * --><!-- * JFreeReport. * --><!-- ***************************************************************** -- ><report-definition name="First Report"> <!-- ************************ --> <!-- * PARSER CONFIGURATION * --> <!-- ************************ --> <parser-config> <object-factory class="org.jfree.report.modules.parser.ext.factory.objects.DefaultClassFactory"/> <element-factory class="org.jfree.report.modules.parser.ext.factory.elements.DefaultElementFactory"/> <stylekey-factory class="org.jfree.report.modules.parser.ext.factory.stylekey.DefaultStyleKeyFactory"/> <stylekey-factory class="org.jfree.report.modules.parser.ext.factory.stylekey.PageableLayoutStyleKeyFactory"/> <template-factory class="org.jfree.report.modules.parser.ext.factory.templates.DefaultTemplateCollection"/> <datasource-factory class="org.jfree.report.modules.parser.ext.factory.datasource.DefaultDataSourceFactory"/> </parser-config> <!-- ************************ --> <!-- * REPORT CONFIGURATION * --> <!-- ************************ --> <report-config> <defaultpageformat orientation="portrait" pageformat="LETTER" topmargin="72" bottommargin="72" leftmargin="72" rightmargin="72"/> </report-config> <!-- ********** --> <!-- * STYLES * --> <!-- ********** --> <styles> <style name="medium-line"> <compound-key name="min-size"> <basic-object name="height">0.0</basic-object> <basic-object name="width">-100.0</basic-object> </compound-key> <basic-key name="paint">black</basic-key> <basic-key name="stroke" class="java.awt.BasicStroke">0.5</basic-key> <basic-key name="draw-shape">true</basic-key> <basic-key name="scale">true</basic-key> </style> <style name="background-rectangle"> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">0.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">-100.0</basic-object> <basic-object name="width">-100.0</basic-object> </compound-key> <basic-key name="fill-shape">true</basic-key> <basic-key name="scale">true</basic-key> </style> </styles> <!-- ********************** --> <!-- * REPORT DESCRIPTION * --> <!-- ********************** --> <report-description> <!-- ================= --> <!-- = REPORT HEADER = --> <!-- ================= --> <report-header name="report-header-band"> <style> <compound-key name="min-size"> <basic-object name="height">112.0</basic-object> <basic-object name="width">0.0</basic-object> </compound-key> </style> <default-style> <basic-key name="font">SansSerif</basic-key> <basic-key name="font-size">10</basic-key> <basic-key name="valignment">bottom</basic-key> </default-style> <element name="title1" type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">2.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">18.0</basic-object> <basic-object name="width">-100.0</basic-object> </compound-key> <basic-key name="alignment">center</basic-key> <basic-key name="font-size">18</basic-key> <basic-key name="font-bold">true</basic-key> </style> <template references="label"> <basic-object name="content">Java Look and Feel Graphics Repository</basic-object> </template> </element> <element name="description1" type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">32.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">10.0</basic-object> <basic-object name="width">-100.0</basic-object> </compound-key> </style> <template references="label"> <basic-object name="content">This report lists the icons contained in the Java Look and Feel Graphics Repository.</basic-object> </template> </element> <element name="description2" type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">44.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">10.0</basic-object> <basic-object name="width">-100.0</basic-object> </compound-key> </style> <template references="label"> <basic-object name="content">For more information about the repository, refer to:</basic-object> </template> </element> <element name="url1" type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">68.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">10.0</basic-object> <basic-object name="width">-100.0</basic-object> </compound-key> <basic-key name="alignment">center</basic-key> <basic-key name="font">Monospaced</basic-key> <basic-key name="font-size">9</basic-key> </style> <template references="label"> <basic-object name="content">http://developer.java.sun.com/developer/techDocs/hi/repository/</basic- object> </template> </element> <element name="description3" type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">92.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">10.0</basic-object> <basic-object name="width">-100.0</basic-object> </compound-key> </style> <template references="label"> <basic-object name="content">The design of this report is described in the JFreeReport PDF documentation.</basic-object> </template> </element> </report-header> <!-- ================= --> <!-- = REPORT FOOTER = --> <!-- ================= --> <report-footer name="report-footer-band"> <style> <compound-key name="min-size"> <basic-object name="height">30.0</basic-object> <basic-object name="width">0.0</basic-object> </compound-key> </style> <default-style> <basic-key name="font">SansSerif</basic-key> <basic-key name="font-size">12</basic-key> <basic-key name="font-bold">true</basic-key> <basic-key name="valignment">bottom</basic-key> </default-style> <element name="rect1" type="shape/generic"> <style> <extends name="background-rectangle"/> <basic-key name="paint">#ccffcc</basic-key> </style> <template references="rectangle"/> </element> <element type="shape/generic"> <style> <extends name="medium-line"/> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">0.0</basic-object> </compound-key> </style> <template references="horizontal-line"/> </element> <element type="shape/generic"> <style> <extends name="medium-line"/> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">30.0</basic-object> </compound-key> </style> <template references="horizontal-line"/> </element> <element name="reportTotalLabel" type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">10.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">12.0</basic-object> <basic-object name="width">-50.0</basic-object> </compound-key> <basic-key name="alignment">left</basic-key> </style> <template references="label"> <basic-object name="content">REPORT TOTAL:</basic-object> </template> </element> <element name="reportCountField" type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">-50.0</basic-object> <basic-object name="y">10.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">9.0</basic-object> <basic-object name="width">-30.0</basic-object> </compound-key> <basic-key name="alignment">center</basic-key> <basic-key name="font-size">9</basic-key> </style> <template references="number-field"> <basic-object name="field">OverallCount</basic-object> <basic-object name="format">#0</basic-object> <basic-object name="nullValue">-</basic-object> </template> </element> <element name="reportSumField" type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">-80.0</basic-object> <basic-object name="y">10.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">9.0</basic-object> <basic-object name="width">-20.0</basic-object> </compound-key> <basic-key name="font-size">9</basic-key> <basic-key name="alignment">right</basic-key> <basic-key name="valignment">bottom</basic-key> </style> <template references="number-field"> <basic-object name="field">OverallSum</basic-object> <basic-object name="format">#,##0</basic-object> <basic-object name="nullValue">-</basic-object> </template> </element> </report-footer> <!-- =============== --> <!-- = PAGE HEADER = --> <!-- =============== --> <page-header> <style> <compound-key name="min-size"> <basic-object name="height">18.0</basic-object> <basic-object name="width">0.0</basic-object> </compound-key> <basic-key name="display-on-firstpage">false</basic-key> <basic-key name="display-on-lastpage">true</basic-key> </style> <default-style> <basic-key name="font-bold">true</basic-key> <basic-key name="font-size">9</basic-key> <basic-key name="font">SansSerif</basic-key> <basic-key name="font-italic">false</basic-key> <basic-key name="paint">black</basic-key> <basic-key name="valignment">bottom</basic-key> </default-style> <element type="shape/generic"> <style> <extends name="background-rectangle"/> <basic-key name="paint">#afafaf</basic-key> </style> <template references="rectangle"/> </element> <element type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">0.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">14.0</basic-object> <basic-object name="width">-50.0</basic-object> </compound-key> <basic-key name="alignment">left</basic-key> </style> <template references="label"> <basic-object name="content">Java Look and Feel Graphics Repository</basic-object> </template> </element> <element type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">-80.0</basic-object> <basic-object name="y">0.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">14.0</basic-object> <basic-object name="width">-20.0</basic-object> </compound-key> <basic-key name="alignment">right</basic-key> </style> <template references="date-field"> <basic-object name="nullValue">-</basic-object> <basic-object name="format">d-MMM-yyyy</basic-object> <basic-object name="field">report.date</basic-object> </template> </element> <element type="shape/generic"> <style> <extends name="medium-line"/> <basic-key name="stroke" class="java.awt.BasicStroke">2.0</basic-key> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">16.0</basic-object> </compound-key> <basic-key name="paint">#cfcfcf</basic-key> </style> <template references="horizontal-line"/> </element> </page-header> <!-- =============== --> <!-- = PAGE FOOTER = --> <!-- =============== --> <page-footer> <style> <basic-key name="display-on-lastpage">true</basic-key> <basic-key name="display-on-firstpage">true</basic-key> <compound-key name="min-size"> <basic-object name="height">14.0</basic-object> <basic-object name="width">0.0</basic-object> </compound-key> </style> <default-style> <basic-key name="font-bold">false</basic-key> <basic-key name="font-size">9</basic-key> <basic-key name="font">SansSerif</basic-key> <basic-key name="font-italic">false</basic-key> </default-style> <element type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">3.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">9.0</basic-object> <basic-object name="width">-100.0</basic-object> </compound-key> <basic-key name="alignment">center</basic-key> <basic-key name="valignment">bottom</basic-key> </style> <template references="number-field"> <basic-object name="nullValue">-</basic-object> <basic-object name="format">Page #0</basic-object> <basic-object name="field">PageNumber</basic-object> </template> </element> </page-footer> <!-- ========== --> <!-- = GROUPS = --> <!-- ========== --> <groups> <!-- category group --> <group name="Category"> <fields> <field>Category</field> </fields> <group-header> <style> <compound-key name="min-size"> <basic-object name="height">30.0</basic-object> <basic-object name="width">0.0</basic-object> </compound-key> </style> <default-style> <!-- use such font name & encoding for displaying chinese --> <basic-key name="font">STSong-Light</basic-key> <basic-key name="font-encoding">UniGB-UCS2-H</basic-key> <basic-key name="font-size">12</basic-key> <basic-key name="font-bold">true</basic-key> <basic-key name="font-italic">false</basic-key> <basic-key name="paint">black</basic-key> <basic-key name="alignment">left</basic-key> <basic-key name="valignment">bottom</basic-key> </default-style> <element type="shape/generic"> <style> <extends name="background-rectangle"/> <basic-key name="paint">#ccccff</basic-key> </style> <template references="rectangle"/> </element> <element type="shape/generic"> <style> <extends name="medium-line"/> <basic-key name="paint">black</basic-key> </style> <template references="horizontal-line"/> </element> <element type="shape/generic"> <style> <extends name="medium-line"/> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">30.0</basic-object> </compound-key> <basic-key name="paint">black</basic-key> </style> <template references="horizontal-line"/> </element> <element type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">3.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">12.0</basic-object> <basic-object name="width">92.0</basic-object> </compound-key> </style> <template references="label"> <basic-object name="content">分类:</basic-object> </template> </element> <element type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">96.0</basic-object> <basic-object name="y">3.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">12.0</basic-object> <basic-object name="width">120.0</basic-object> </compound-key> </style> <template references="string-field"> <basic-object name="nullValue">-</basic-object> <basic-object name="field">Category</basic-object> </template> </element> <element type="text/plain"> <style> <basic-key name="font-size">8</basic-key> <basic-key name="font-bold">false</basic-key> <basic-key name="font-italic">true</basic-key> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">20.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">9.0</basic-object> <basic-object name="width">-50.0</basic-object> </compound-key> </style> <template references="label"> <basic-object name="content">名称:</basic-object> </template> </element> <element type="text/plain"> <style> <basic-key name="font-size">8</basic-key> <basic-key name="font-bold">false</basic-key> <basic-key name="font-italic">true</basic-key> <basic-key name="paint">black</basic-key> <compound-key name="absolute_pos"> <basic-object name="x">-50.0</basic-object> <basic-object name="y">20.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">9.0</basic-object> <basic-object name="width">-30.0</basic-object> </compound-key> </style> <template references="label"> <basic-object name="content">图标:</basic-object> </template> </element> <element type="text/plain"> <style> <basic-key name="font-size">8</basic-key> <basic-key name="font-bold">false</basic-key> <basic-key name="font-italic">true</basic-key> <basic-key name="alignment">right</basic-key> <compound-key name="absolute_pos"> <basic-object name="x">-80.0</basic-object> <basic-object name="y">20.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">9.0</basic-object> <basic-object name="width">-20.0</basic-object> </compound-key> </style> <template references="label"> <basic-object name="content">文件大小:</basic-object> </template> </element> </group-header> <group-footer> <style> <compound-key name="min-size"> <basic-object name="height">30.0</basic-object> <basic-object name="width">0.0</basic-object> </compound-key> <basic-key name="pagebreak-before">false</basic-key> </style> <default-style> <basic-key name="font">SansSerif</basic-key> <basic-key name="font-size">11</basic-key> <basic-key name="font-bold">true</basic-key> <basic-key name="font-italic">false</basic-key> <basic-key name="valignment">bottom</basic-key> </default-style> <element type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">5.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">11.0</basic-object> <basic-object name="width">100.0</basic-object> </compound-key> <basic-key name="alignment">left</basic-key> </style> <template references="label"> <basic-object name="content">Group Total:</basic-object> </template> </element> <element type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">-50.0</basic-object> <basic-object name="y">5.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">9.0</basic-object> <basic-object name="width">-30.0</basic-object> </compound-key> <basic-key name="alignment">center</basic-key> <basic-key name="font-size">9</basic-key> </style> <template references="number-field"> <basic-object name="nullValue">-</basic-object> <basic-object name="format">#0</basic-object> <basic-object name="field">GroupCount</basic-object> </template> </element> <element type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">-80.0</basic-object> <basic-object name="y">5.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">9.0</basic-object> <basic-object name="width">-20.0</basic-object> </compound-key> <basic-key name="font-size">9</basic-key> <basic-key name="alignment">right</basic-key> </style> <template references="number-field"> <basic-object name="nullValue">-</basic-object> <basic-object name="format">#,##0</basic-object> <basic-object name="field">GroupSum</basic-object> </template> </element> </group-footer> </group> </groups> <!-- ============= --> <!-- = ITEM BAND = --> <!-- ============= --> <itemband> <style> <compound-key name="min-size"> <basic-object name="height">26.0</basic-object> <basic-object name="width">0.0</basic-object> </compound-key> </style> <default-style> <basic-key name="font">STSong-Light</basic-key> <basic-key name="font-encoding">UniGB-UCS2-H</basic-key> <basic-key name="font-size">10</basic-key> <basic-key name="valignment">bottom</basic-key> </default-style> <element type="shape/generic"> <style> <extends name="medium-line"/> <basic-key name="stroke" class="java.awt.BasicStroke">0.1</basic-key> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">25.0</basic-object> </compound-key> <basic-key name="paint">#dfdfdf</basic-key> </style> <template references="horizontal-line"/> </element> <!-- element to display the name from the TableModel --> <element type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">0.0</basic-object> <basic-object name="y">8.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">10.0</basic-object> <basic-object name="width">-50.0</basic-object> </compound-key> <basic-key name="alignment">left</basic-key> </style> <template references="string-field"> <basic-object name="nullValue">-</basic-object> <basic-object name="field">Name</basic-object> </template> </element> <!-- element to display icon from the TableModel --> <element type="image/generic"> <style> <compound-key name="absolute_pos"> <basic-object name="x">-50.0</basic-object> <basic-object name="y">1.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">24.0</basic-object> <basic-object name="width">-30.0</basic-object> </compound-key> <basic-key name="alignment">center</basic-key> <basic-key name="valignment">middle</basic-key> </style> <template references="image-field"> <basic-object name="field">Icon</basic-object> </template> </element> <!-- element to display the file size from the TableModel --> <element type="text/plain"> <style> <compound-key name="absolute_pos"> <basic-object name="x">-80.0</basic-object> <basic-object name="y">8.0</basic-object> </compound-key> <compound-key name="min-size"> <basic-object name="height">10.0</basic-object> <basic-object name="width">-20.0</basic-object> </compound-key> <basic-key name="alignment">right</basic-key> </style> <template references="number-field"> <basic-object name="nullValue">-</basic-object> <basic-object name="format">#,##0</basic-object> <basic-object name="field">Size</basic-object> </template> </element> </itemband> </report-description> <!-- ************* --> <!-- * FUNCTIONS * --> <!-- ************* --> <functions> <property-ref name="report.date"/> <function name="PageNumber" class="org.jfree.report.function.PageFunction"/> <function name="GroupCount" class="org.jfree.report.function.ItemCountFunction"> <properties> <property name="field">Name</property> <property name="group">Category</property> </properties> </function> <function name="GroupSum" class="org.jfree.report.function.ItemSumFunction"> <properties> <property name="field">Size</property> <property name="group">Category</property> </properties> </function> <function name="OverallCount" class="org.jfree.report.function.ItemCountFunction"> <properties> <property name="field">Name</property> </properties> </function> <function name="OverallSum" class="org.jfree.report.function.ItemSumFunction"> <properties> <property name="field">Size</property> </properties> </function> </functions> </report-definition>

    总结

    这是自认为目前非常好的的Web应用的打印解决方案,虽然仅使用jfreereport产生pdf文件的功能,但是jfreereport提供的页面自动布置的功能使产生报表的工作较之使用iText直接产生要方便许多。以上的例子理论上可以在任何的符合j2ee 1.3规范(或部分符合,如tomcat 4.x)的应用服务器上运行,我仅仅在was 5.0.x上进行了测试。仅供大家参考。

0
相关文章