论坛首页 Java企业应用论坛

用Main方法调用freemarker生成文本文件

浏览 5011 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-12-02  
需求:一些金融机构需要很多报表,比如资产负债表,他们希望按照以往的习惯把报表放在一个文本文件里面,并且用空格和横竖线划成表格的样子,最终可以用于打印或者字符终端显示。报表文本文件样子如下:(html里面对不齐,可以用记事本打开附件)。
xml 代码
  1. +------------------------------------------------------------------------  
  2. |             资产           | 行 |  期初数          |  期末数          |  
  3. |                            | 次 |                  |                  |  
  4. |----------------------------+----+------------------+------------------+  
  5. |流动资产                    |0001|              0.00|              0.00|  
  6. |----------------------------+----+------------------+------------------+  
  7. |  现金及周转金              |0002|     96,482,019.59|     96,482,019.59|  
  8. |----------------------------+----+------------------+------------------+  
  9. |  存放中央银行款项          |0003|              0.00|              0.00|  
  10. |----------------------------+----+------------------+------------------+  
  11. |  专项央行票据              |0004|              0.00|              0.00|  
  12. |----------------------------+----+------------------+------------------+  
  13. |  央行专项扶持资金          |0005|              0.00|              0.00|  
  14. |----------------------------+----+------------------+------------------+  
  15. |  存放同业款项              |0006|              0.00|              0.00|  
  16. |----------------------------+----+------------------+------------------+  
  17. |  存放联行款项              |0007|              0.00|              0.00|  
  18. |----------------------------+----+------------------+------------------+  
  19. |  拆放同业                  |0008|              0.00|              0.00|  
  20. |----------------------------+----+------------------+------------------+  
  21. |  拆放金融性公司            |0009|              0.00|              0.00|  
  22. |----------------------------+----+------------------+------------------+  
  23.                                                                            

实现:报表数据在数据库,可以用jdbc查询出来,最终要生成文件,不由想到使用freemarker,那还需要的就是画一个ftl模版。
针对最终的文件形式,ftl如下:
java 代码
 
  1.  %%${organization.number}  
  2. <#assign prepage=0>  
  3. <#assign pagenumber=30>  
  4. <#assign currentnumber=0>  
  5. <#assign currentpage=1>  
  6. <#list rows as row>  
  7. <#if (prerow?exists && prerow.curr_cd != row.curr_cd)>  
  8. <#assign currentpage = currentpage + 1>  
  9. <#assign currentnumber=0>  
  10.   +-----------------------------------------------------------------------------------------------------------------------------------------------+  
  11.        事后监督                         主管                            复核                         制表                    报表日期   ${date?string("yyyy/MM/dd")}  
  12. <!---->if>  
  13. <#if currentnumber % pagenumber == 0>                                                     @@ xx金融机构资产负债表 &&  
  14.    单位名称  ${organization.name}                           报表类型  日报         制表日期  ${date?string("yyyy")}   年  ${date?string("MM")}  月  ${date?string("dd")}  日        币种  ${row.curr_cd}  
  15.                                                                                                        单位: 元                第      ${currentpage}   页  
  16.   +-----------------------------------------------------------------------------------------------------------------------------------------------+  
  17.   |             资产           | 行 |  期初数          |  期末数          |             资产           | 行 |  期初数          |  期末数          |  
  18.   |                            | 次 |                  |                  |                            | 次 |                  |                  |  
  19. <!---->if>  
  20.   |----------------------------+----+------------------+------------------+----------------------------+----+------------------+------------------|  
  21.   |${row.item_name}|${row.line_no?string("0000")}|${row.begin_bal?string("#,##0.00")?left_pad(18)}|${row.end_bal?string("#,##0.00")?left_pad(18)}|${row.item_name2}|${row.line_no?string("0000")}|${row.begin_bal2?string("#,##0.00")?left_pad(18)}|${row.end_bal2?string("#,##0.00")?left_pad(18)}|  
  22. <#if (currentnumber % pagenumber == pagenumber - 1) || (row_has_next == false)>  
  23.   +-----------------------------------------------------------------------------------------------------------------------------------------------+  
  24.        事后监督                         主管                            复核                         制表                    报表日期   ${date?string("yyyy/MM/dd")}  
  25. <#assign currentpage = currentpage + 1><!---->if>  
  26. <#assign prerow = row>  
  27. <#assign prepage = currentpage>  
  28. <#assign currentnumber = currentnumber + 1>  
  29. <!---->  

生成文件的Main方法代码如下:
java 代码
 
  1. import java.io.BufferedWriter;  
  2. import java.io.File;  
  3. import java.io.FileWriter;  
  4. import java.io.IOException;  
  5. import java.sql.Connection;  
  6. import java.sql.Date;  
  7. import java.sql.DriverManager;  
  8. import java.sql.PreparedStatement;  
  9. import java.sql.ResultSet;  
  10. import java.text.SimpleDateFormat;  
  11. import java.util.ArrayList;  
  12. import java.util.HashMap;  
  13. import java.util.List;  
  14. import java.util.Map;  
  15.   
  16. import freemarker.template.Configuration;  
  17. import freemarker.template.DefaultObjectWrapper;  
  18. import freemarker.template.Template;  
  19.   
  20. /** 
  21.  * @author arthur 
  22.  * @version $Revision: 1.1 $ 
  23.  */  
  24.   
  25. public class Test {  
  26.   
  27.     public static void main(String[] args) throws Exception {  
  28.         Class.forName("com.ibm.db2.jcc.DB2Driver");  
  29.   
  30.         Connection conn = DriverManager.getConnection("jdbc:db2://ip:port/dbname""username""pwd");  
  31.   
  32.         StringBuffer sb = new StringBuffer(  
  33.                 "select record_date,cycle_no,bank_no,curr_cd,line_no,item_name,item_no,begin_bal,end_bal,item_name2,item_no2,begin_bal2,end_bal2 from FIN_BALANCE_REPORT ");  
  34.         sb.append("where RECORD_DATE = ?");  
  35.         sb.append("order by cycle_no,BANK_NO,CURR_CD,line_no");  
  36.         PreparedStatement pstmt = conn.prepareStatement(sb.toString());  
  37.         Date date = Date.valueOf("2006-6-30");  
  38.         pstmt.setDate(1, date);  
  39.         ResultSet rs = pstmt.executeQuery();  
  40.         Map root = new HashMap();  
  41.         List rows = new ArrayList();  
  42.         Map org = new HashMap();  
  43.         int pre_cycle_no = -1;  
  44.         String pre_bank_no = "";  
  45.         while (rs.next()) {  
  46.             Map row = new HashMap();  
  47.             int cycle_no = rs.getInt("cycle_no");  
  48.             String bank_no = rs.getString("bank_no");  
  49.             if (pre_cycle_no != -1 && pre_cycle_no != cycle_no  
  50.                     || (pre_bank_no.length() > 0 && !pre_bank_no.equals(bank_no))) {// 另外一个cycle_no和bank_no  
  51.                 org.put("number", pre_bank_no);  
  52.                 org.put("name", pre_bank_no);  
  53.                 root.put("organization", org);  
  54.                 root.put("date", date);  
  55.                 root.put("rows", rows);  
  56.   
  57.                 Configuration cfg = new Configuration();  
  58.                 cfg.setDirectoryForTemplateLoading(new File("D:/work/template/"));  
  59.                 cfg.setObjectWrapper(new DefaultObjectWrapper());  
  60.                 Template temp = cfg.getTemplate("资产负债表.ftl");  
  61.                 String dateString = new SimpleDateFormat("yyyyMMdd").format(date);  
  62.                 String fileName = "T" + pre_bank_no + "_" + dateString + "_" + pre_cycle_no + pre_bank_no;  
  63.                 File file = new File("D:/work/dest/" + fileName);  
  64.                 FileWriter fw = new FileWriter(file);  
  65.                 try {  
  66.                     BufferedWriter bw = new BufferedWriter(fw);  
  67.                     temp.process(root, bw);  
  68.                     bw.flush();  
  69.                 } catch (IOException e) {  
  70.                     e.printStackTrace();  
  71.                 } finally {  
  72.                     fw.close();  
  73.                 }  
  74.                 rows = new ArrayList();  
  75.             }  
  76.             int line_no = rs.getInt("line_no");  
  77.             row.put("line_no"new Integer(line_no));  
  78.             row.put("item_name", rightPad(rs.getString("item_name"), 28));  
  79.             row.put("begin_bal", rs.getBigDecimal("begin_bal"));  
  80.             row.put("end_bal", rs.getBigDecimal("end_bal"));  
  81.             row.put("item_name2", rightPad(rs.getString("item_name2"), 28));  
  82.             row.put("begin_bal2", rs.getBigDecimal("begin_bal2"));  
  83.             row.put("end_bal2", rs.getBigDecimal("end_bal2"));  
  84.             row.put("curr_cd", rs.getString("curr_cd"));  
  85.   
  86.             rows.add(row);  
  87.   
  88.             root = new HashMap();  
  89.             pre_cycle_no = cycle_no;  
  90.             pre_bank_no = bank_no;  
  91.         }  
  92.   
  93.         rs.close();  
  94.         pstmt.close();  
  95.         conn.close();  
  96.   
  97.     }  
  98.   
  99.     /** 
  100.      * 汉字算2位的右边补齐空格方法 
  101.      */  
  102.     public static String rightPad(String s, int minLength) {  
  103.         int ln = length(s);  
  104.         if (minLength <= ln) {  
  105.             return s;  
  106.         }  
  107.   
  108.         StringBuffer res = new StringBuffer(minLength);  
  109.   
  110.         res.append(s);  
  111.   
  112.         int dif = minLength - ln;  
  113.         for (int i = 0; i < dif; i++) {  
  114.             res.append(' ');  
  115.         }  
  116.   
  117.         return res.toString();  
  118.     }  
  119.   
  120.     /** 
  121.      * 汉字算2位的左边补齐空格方法 
  122.      */  
  123.     public static String leftPad(String s, int minLength) {  
  124.         int ln = length(s);  
  125.         if (minLength <= ln) {  
  126.             return s;  
  127.         }  
  128.   
  129.         StringBuffer res = new StringBuffer(minLength);  
  130.   
  131.         int dif = minLength - ln;  
  132.         for (int i = 0; i < dif; i++) {  
  133.             res.append(' ');  
  134.         }  
  135.   
  136.         res.append(s);  
  137.   
  138.         return res.toString();  
  139.     }  
  140.   
  141.     /** 
  142.      * 汉字算2位的String length计算方法 
  143.      */  
  144.     public static int length(String s) {  
  145.         int counter = 0;  
  146.         for (int i = 0; i < s.length(); i++) {  
  147.             char c = s.charAt(i);  
  148.             if (c < 255) {  
  149.                 counter++;  
  150.             } else {  
  151.                 counter = counter + 2;  
  152.             }  
  153.         }  
  154.         return counter;  
  155.     }  
  156. }  

这个代码很不完善,比如没有异常捕获、Log机制、目标目录和用到的模版文件都是写死,仅仅作为测试使用。
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics