# Jasper Report 開發
## 報表狀態追蹤
[報表狀態追蹤](https://docs.google.com/spreadsheets/d/1n-3vy1XRqLclvDMgUSpwe5dmZiXZAepvvTWDT3zW7Ew/edit#gid=0)
## 共用規格
### Style
```xml=
<style name="title" forecolor="#000000" hTextAlign="Center" vTextAlign="Middle" isBlankWhenNull="false" fontName="標楷體" fontSize="14" isBold="true"/>
<style name="label" forecolor="#000000" hTextAlign="Left" vTextAlign="Middle" isBlankWhenNull="false" fontName="標楷體" fontSize="10" isBold="false">
<box leftPadding="3" rightPadding="3"/>
</style>
<style name="header" style="label" hTextAlign="Center"/>
<style name="memo" style="label" vTextAlign="Top" isBold="false"/>
<style name="footer" style="label" hTextAlign="Right"/>
<style name="field" forecolor="#000000" hTextAlign="Left" vTextAlign="Top" isBlankWhenNull="true" fontName="標楷體" fontSize="10" isBold="false">
<box topPadding="2" leftPadding="3" bottomPadding="2" rightPadding="3"/>
</style>
<style name="number" style="field" hTextAlign="Right" pattern="#,##0"/>
<style name="average" style="number" pattern="#,##0.00" isBlankWhenNull="true"/>
<style name="percent" style="number" pattern="#0.00%" isBlankWhenNull="true"/>
<style name="date" style="field" pattern="yyyy/MM/dd"/>
<style name="time" style="field" pattern="hh:mm"/>
<style name="datetime" style="field" pattern="yyyy/MM/dd HH:mm"/>
<style name="data change style">
<conditionalStyle>
<conditionExpression><![CDATA[$V{REPORT_COUNT} % 2 == 1]]></conditionExpression>
<style mode="Opaque" backcolor="#F2F2F2"/>
</conditionalStyle>
</style>
```
### 製表者
```Java
org.apache.commons.lang3.StringUtils.defaultString($P{userId}) + " " + org.apache.commons.lang3.StringUtils.defaultString($P{userName)
```
### 製表日期時間/頁次
```xml=
<textField pattern="yyyy/MM/dd HH:mm:ss">
<reportElement key="" style="datetime" x="660" y="0" width="140" height="30" forecolor="#000000" uuid="3b93d210-b949-44f1-b42a-d9842f0b0e34"/>
<textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression>
</textField>
<textField>
<reportElement key="" style="label" x="660" y="30" width="50" height="20" forecolor="#000000" uuid="72a396a2-7bd6-408b-af34-826e3446e298"/>
<textFieldExpression><![CDATA["Page: " + $V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement key="" style="label" x="710" y="30" width="90" height="20" forecolor="#000000" uuid="4552ebc1-f5a9-4a8b-bad0-297cf925b2e8"/>
<textFieldExpression><![CDATA[" of " + $V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
```
### 製表者/搜尋條件
```xml=
<textField>
<reportElement style="footer" x="0" y="20" width="100" height="20" forecolor="#000000" uuid="6cbfcf90-f95b-4e2e-b90a-b634d03c52f9"/>
<textFieldExpression><![CDATA[$P{pms01r0180parameter6}]]></textFieldExpression>
</textField>
<textField>
<reportElement key="" style="field" x="100" y="20" width="700" height="20" forecolor="#000000" uuid="21fdab5d-d35c-4d4d-9551-5f10012964d4"/>
<textFieldExpression><![CDATA[org.apache.commons.lang3.StringUtils.defaultString($P{userId}) + " " + org.apache.commons.lang3.StringUtils.defaultString($P{userName})]]></textFieldExpression>
</textField>
<textField>
<reportElement style="footer" x="0" y="40" width="100" height="20" uuid="0d5ee6e3-6b4a-4bbb-aec1-4d619275dabb"/>
<textFieldExpression><![CDATA[$P{pms01r0180parameter7}]]></textFieldExpression>
</textField>
<textField>
<reportElement key="" style="field" x="100" y="40" width="700" height="20" uuid="495434f6-afbb-4f89-98b1-0c5e4823ea1b"/>
<textFieldExpression><![CDATA[$P{pms01r0180parameter4}]]></textFieldExpression>
</textField>
```
## 常用欄位寬度
| 欄位 | 字元數 | 長度 |
| :-- | --: | --: |
| 日期 | 10 | 70 |
| 時間 | 5 | 70 |
| 日期時間 | 16 | 70 |
| 訂房卡號 | 8 | 70 |
| 訂房卡序號 | 2 | 40 |
| 訂房卡號+序號 | 11 | 80 |
| 房型代碼 | 4 | 60 |
| 房號 | 4 | 40 |
| 金額 | 9 | 70 |
| 訂金編號 | 10 | 80 |
| 姓名 | 4 `Min` | 60 |
| 發票號碼 | 10 | 80 |
| 統一編號 | 8 | 60 |
| 訂單編號 | 21 | 120 |
| 信用卡卡號 | 16 | 100 |
| 班別 | 1 | 40 |
| 房價代碼 | 8 | 60 |
| VIP | 1 | 40 |
| 電話 | 10 | 70 |
| 國籍簡稱 | 10 | 80 |
| 百分比 | 7 `100.00%` | 50 |
| 使用者ID | 10 | 70 |
## 語法
### 數字依參數格式化
```java=
new java.text.DecimalFormat($P{numberFormat}).format($f{fieldName})
```
```xml=
<!-- 接收從 Java 傳來的數字格式 -->
<parameter name="numberFormat" class="java.lang.String"/>
<!-- 設定顯示格式 -->
<textFieldExpression><![CDATA[new java.text.DecimalFormat($P{numberFormat}).format($f{fieldName})]]></textFieldExpression>
```
### 日期依參數格式化
```java=
new java.text.simpledateformat($P{dateFormat}).format($f{fieldName})
```
```xml=
<!-- 接收從 Java 傳來的日期格式 -->
<parameter name="dateFormat" class="java.lang.String"/>
<!-- 設定顯示格式 -->
<textFieldExpression><![CDATA[new java.text.simpledateformat($P{dateFormat}).format($f{fieldName})]]></textFieldExpression>
```
### 日期直接強制轉換為全英文
```java=
new java.text.SimpleDateFormat("EEEEEEEEE, MMMMMMMMM d, yyyy", Locale.ENGLISH).format($F{fieldName})
```
### 判斷是否是最後一筆明細
```java=
$V{REPORT_COUNT} == Integer.valueOf($P{size})
```
```xml=
<parameter name="size" class="java.lang.String"/>
<band height="20">
<printWhenExpression><![CDATA[$V{REPORT_COUNT} == Integer.valueOf($P{size})]]></printWhenExpression>
</band>
```
## 設定技巧
### 設定 Subreport
1. 設定子報表參數

```xml=
<parameter name="subReport" class="net.sf.jasperreports.engine.util.JRResourcesUtil"/>
```
2. 設定子報表資料集

```xml=
<field name="subDataList" class="net.sf.jasperreports.engine.data.JRMapCollectionDataSource"/>
```
3. 設定要讀取的子報表

```java=
// 路徑:/{報表路徑|套表路徑}/{模組資料夾}/{子報表檔案名稱}
JasperCompileManager.compileReportToFile($P{subReport}.findClassLoaderResource("/DefaultTemplate/{模組資料夾}/{子報表檔案名稱}",null).getPath())
```
```xml=
<parameter name="subReport" class="net.sf.jasperreports.engine.util.JRResourcesUtil"/>
<field name="subDataList" class="net.sf.jasperreports.engine.data.JRMapCollectionDataSource"/>
<subreport>
<dataSourceExpression><![CDATA[$F{subDataSet}]]></dataSourceExpression>
<subreportExpression><![CDATA[JasperCompileManager.compileReportToFile($P{subReport}.findClassLoaderResource("/DefaultTemplate/01/pms01r-1sub.jrxml",null).getPath())]]></subreportExpression>
</subreport>
```
### 設定一個父報表依不同查詢條件載入不同子報表
1. 設定子報表查詢條件參數
```xml=
<parameter name="subReportType" class="java.lang.String"/>
```
2. 設定不同子報表使用不同 Detail Band
```xml=
<detail>
<band height="32">
<printWhenExpression><![CDATA[$P{subReportType}.equalsIgnoreCase( "room" )]]></printWhenExpression>
<subreport><!-- 省略 --></subreport>
</band>
<band height="32">
<printWhenExpression><![CDATA[$P{subReportType}.equalsIgnoreCase( "all" )]]></printWhenExpression>
<subreport><!-- 省略 --></subreport>
</band>
</detail>
```
### 設定 Subreport 多語
1. 設定父報表多語參數

2. 設定要傳入子報表的多語參數
* 僅設定要傳入特定參數

* 設定傳入全部參數

```xml=
<subreport>
<reportElement x="0" y="0" width="800" height="48" uuid="cd2f69a0-fb5b-43b0-be3f-86e0f7dd77cc"/>
<!-- 要傳入的參數 -->
<subreportParameter name="pms01r0180parameter9">
<subreportParameterExpression><![CDATA[$P{pms01r0180parameter9}]]></subreportParameterExpression>
</subreportParameter>
<!-- 省略 -->
</subreport>
```
3. 設定子報表多語參數

### 設定 Crosstab 多語
1. 設定參數

```xml=
<parameter name="pms01r0180parameter9" class="java.lang.String"/>
```
2. Crosstab 設定要接收的參數


```xml=
<parametersMapExpression><![CDATA[$P{REPORT_PARAMETERS_MAP}]]></parametersMapExpression>
```
3. 在 Crosstab 讀取多語參數

```java=
$P{REPORT_PARAMETERS_MAP}.get( "{LanguageParameterName}" )
```
```xml=
<textField>
<reportElement style="label" x="0" y="0" width="90" height="32" uuid="0c16cae7-ff77-41ed-a175-c481f63d5d50"/>
<textFieldExpression><![CDATA[$P{REPORT_PARAMETERS_MAP}.get( "pms01r0180parameter9" )]]></textFieldExpression>
</textField>
```