2

さまざまな XML データソースで機能する共有 (テンプレート) .JRXML ファイルが必要です。

これを防ぐ可能性があると私が知っている唯一のことは、フィールドの仕様がわずかに異なるということです。

1 つの XML ファイルの場合、名前フィールドの XPATH は次のようになります。

   person/name/last

別の XML ファイルの場合、XPATH は次のようになります。

   contact/last_name

理想的には、XPATH をパラメーターとして渡し、次のように使用できます。

 <field name="name" class="java.lang.String">
    <fieldDescription> $P{NAME_XPATH} </fieldDescription>
</field>

<fieldDescription>しかし、Jasper はタグ でのパラメーターの使用をサポートしていないようです。

フィールド仕様をJRXMLテンプレートに挿入する方法はありますか?

4

2 に答える 2

0

<fieldDescription>Jasper は、タグでのパラメーターの使用をサポートしていません。

Jasper のソースをダウンロードしましたが、代替手段を実装するだけでこの機能を追加できるとは思いませんXPathExecutor。その理由は、パラメータを含むコンテキストが XPathExecutor ファクトリ クラスで使用できないためです。要するに、追加する必要があるコンテキストの受け渡しがたくさんあります。

もちろん、それを追加してみることができますが、それは多くのクラス ファイルに影響を与え、Jasper が認識できない種類の変更になり、分岐したソースを永遠にマージすることになります。

私はそれを危険にさらす準備ができていませんでした。さらに、遅かれ早かれ、ジャスパーがこれを追加すると思います。

ただし、基本的に独自のカスタム XPathExecutor を記述し、Threadlocal 変数の実装を介してコンテキストを渡すという解決策を思いつきました。以下のコード例では、Threadlocal 変数はReportGeneratorJasper.requestContext

static ThreadLocal<ReportRequest> requestContext;    

私のクラスでカスタム XPathExecutor を設定するコードは次のReportGeneratorJasperとおりです。

    JasperReport repResource = getJasperReport(report);
    JasperPrint jp = null;

    // Setup for eReports XPATH executers
    //
    JasperReportsContext jrc = DefaultJasperReportsContext.getInstance();
    jrc.setProperty(
        JRXPathExecuterUtils.PROPERTY_XPATH_EXECUTER_FACTORY, 
        XalanNamedParameterXPathExecutor.class.getCanonicalName());

    requestContext = 
               new ThreadLocal<ReportRequest>() {
                         protected synchronized ReportRequest initialValue() {
                         return request;
             };
    };

    JasperFillManager jfm = JasperFillManager.getInstance(jrc);

ReportRequest は、「この」特定のレポート生成要求を定義するすべてのプロパティを含む私自身の Bean です。

カスタム XPathExecutor (独自のファクトリも提供) を次に示します。:

public class XalanNamedParameterXPathExecutor 
            extends XalanXPathExecuter implements JRXPathExecuterFactory {

    // Reference to the Threadlocal
    //
    private ReportRequest request;

    public static final String PREFIX = "$";

    public XalanNamedParameterXPathExecutor() {
        this.request = ReportGeneratorJasper.requestContext.get();
    }

    @Override
    public Object selectObject(Node arg0, String xpath) throws JRException {

        String useXpath = xpath;

        if (xpath.startsWith("$")) {
            String value = request.getScalarParamAsString(xpath);
            useXpath = (value != null ? value : xpath);         
        }

        return super.selectObject(arg0, useXpath);
    }

    @Override
    public JRXPathExecuter getXPathExecuter() {
        return new XalanNamedParameterXPathExecutor();
    }

Threadlocal の使用は理想的なソリューションではありません。レポート フィラーが別のスレッドで実行されると、破損する傾向があります。しかし、Jasper の現在のバージョンでは問題ないようです。

Jasper がこれに対する組み込みサポートを実装することを願っています。

于 2013-04-02T18:59:19.973 に答える
0

あなたのシステムは XML ベースなので、XSLT を使用しないのはなぜですか? JRXML テンプレートを XSL スタイルシートに適合させると、XML 構成ファイルを入力として使用して、XSLT プロセッサがフィールドの説明を構成コンテンツに置き換えることができます。

例: JRXML/XSL

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/report-config">

    <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd">

    ...

    <field name="name" class="java.lang.String">
        <fieldDescription><xsl:value-of select="name"/></fieldDescription>
    </field>

    ...

    </jasperReport>

  </xsl:template>
</xsl:stylesheet>

XML の構成

<?xml version="1.0" encoding="ISO-8859-1"?>
<report-config>
    <name>person/name/last</name>
</report-config>
于 2013-03-28T15:09:33.067 に答える