感謝史烤酥當初提議,找Contract進來要考試,無意間就考進兩名高手,雖然很愜意的不用寫程式,第一次扮演發號施令的角色,不用再校長兼撞鐘,也因此得以學習到高手程設精髓。目前專案任務是將報表內容轉存成pdf檔,儲存到Oracle的Blob後再response到前端去,現在採倒敍法記錄這些訣竅:

1.把byte array內容response到前端:

byte[] bt = ...; // get byte array from Oracle Blob. See section 2
response.setContentType("application/pdf;charset=big5"); // 這列正是我出的考題之一
response.setHeader("Content-Disposition:", "attachment;filename="+ pdfname);
response.setContentLength(bt.length);
response.getOutputStream().write(bt);
response.getOutputStream().flush();
response.getOutputStream().close();

2.自Oracle取得Blob內容片段:

BLOB blob = null;
ResultSet rset = pstmt.executeQuery();
if (rset.next()) {
    blob = (BLOB) rset.getBlob(1);
}

BufferedInputStream ins = new BufferedInputStream(blob.getBinaryStream());
                                         // Get Blob Stream from Oracle
int bufferSize = (int) blob.length();    // Get the length of Blob
byte[] bt = new byte[bufferSize];        // Declare byte array size
ins.read(bt, 0, bufferSize);             // Write Blob to byte array

3.將PDF內容寫入Oracle片段:

pstmt = conn.prepareStatement(insertSQL);  // 先寫入一筆空的Blob,然後Save
pstmt.setBlob(4, BLOB.empty_lob());
pstmt.executeUpdate();

Blob blob=null;
pstmt = conn.prepareStatement(getSQL);     // 再讀出Blob欄位,獲得Cursor
ResultSet rset = pstmt.executeQuery();
if (rset.next()) {
    blob = (BLOB) rset.getBlob(1);
}

InputStream instream = new FileInputStream(fileName);   // pdf file name(include path)
OutputStream outstream = blob.getBinaryOutputStream();  // Get Blob stream from Oracle
byte[] buffer = new byte[blob.getChunkSize()];          // Declare byte array size
int bytesRead = -1;
while ((bytesRead = instream.read(buffer)) != -1) {     // read pdf to write in Oracle
    outstream.write(buffer, 0, bytesRead);
}

寫Blob所費時間較久,是故先insert空的Blob後commit,再直接對Blob欄位update。

4.用JasperReport產出PDF

本例是使用iReport所出的jrxml為模版產出PDF檔,iReport還不熟,是故只講JasperReport用法。

JasperReport jasperReport = (JasperReport)JRLoader.loadObject(“pdf.jasper”);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource());
JasperExportManager.exportReportToPdfFile(jasperPrint, exportFile);

上面三個紅色的參數為開發者需要傳入和定義。

  • 附檔名為.japser的檔案之於.jrxml相同於.class檔之於.java檔,jrxml被iReport編譯成jasper檔。
  • JRLoader.loadObject的參數是一Expression。若是字串,依序被理解為:URL、File、Class Path,也就是 URL解析有誤,就當File解析;其參數型態亦可以為Jasper的InputStream或JasperReport物件。
  • 事實上也可以執行期把.jrxml編譯成.jasper,用法如下:
    • JasperReport jasperReport = JasperCompileManager.compileReport("reports/Location.jrxml");
  • parameters參數則為一Map形式的Java物件,填充於.jrxml模板內。
  • exportFile則為產出的PDF檔名,為Section 3所用。

arrow
arrow
    全站熱搜

    Jemmy 發表在 痞客邦 留言(0) 人氣()