本篇為使用word功能變數,convert word to pdf,並解決中文顯示問題之延伸,主要說明如何將多個套表檔整合至一支程式,以spring + struts2 + hibernate做開發,呈現其設計模式:
一、DB Schema
1.DTPdfTemplate (PDF版型檔)

2.DTPdfCol (PDF版型欄位檔)

二、hibernate bean
1.DTPdfTemplatePK.java
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class DTPdfTemplatePK implements Serializable {
@Column(name = "kind")
private int kind;
@Column(name = "commSeqno")
private int commSeqno;
public DTPdfTemplatePK() {
}
public DTPdfTemplatePK(int kind, int commSeqno) {
super();
this.kind = kind;
this.commSeqno = commSeqno;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + commSeqno;
result = prime * result + kind;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DTPdfTemplatePK other = (DTPdfTemplatePK) obj;
if (commSeqno != other.commSeqno)
return false;
if (kind != other.kind)
return false;
return true;
}
public int getKind() {
return kind;
}
public void setKind(int kind) {
this.kind = kind;
}
public int getCommSeqno() {
return commSeqno;
}
public void setCommSeqno(int commSeqno) {
this.commSeqno = commSeqno;
}
@Override
public String toString() {
return "DTPdfTemplatePK [kind=" + kind + ", commSeqno=" + commSeqno + "]";
}
}
2.DTPdfTemplate.java
import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "DTPdfTemplate")
public class DTPdfTemplate implements Serializable {
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(
name = "kind",
column = @Column(name = "kind")),
@AttributeOverride(
name = "commSeqno",
column = @Column(name = "commSeqno"))
})
protected DTPdfTemplatePK dtPdfTemplatePK;
@Column(name = "docFileName")
protected String docFileName;
@Column(name = "docType")
protected String docType;
@Column(name = "docSrc")
protected byte[] docSrc;
@Column(name = "modifyTime")
protected Date modifyTime;
@Column(name = "modifyEmp")
protected String modifyEmp;
public DTPdfTemplate() {
}
public DTPdfTemplate(DTPdfTemplatePK dtPdfTemplatePK) {
super();
this.dtPdfTemplatePK = dtPdfTemplatePK;
}
public DTPdfTemplate(DTPdfTemplatePK dtPdfTemplatePK, String docFileName, String docType, byte[] docSrc,
Date modifyTime, String modifyEmp) {
super();
this.dtPdfTemplatePK = dtPdfTemplatePK;
this.docFileName = docFileName;
this.docType = docType;
this.docSrc = docSrc;
this.modifyTime = modifyTime;
this.modifyEmp = modifyEmp;
}
public DTPdfTemplatePK getDtPdfTemplatePK() {
return dtPdfTemplatePK;
}
public void setDtPdfTemplatePK(DTPdfTemplatePK dtPdfTemplatePK) {
this.dtPdfTemplatePK = dtPdfTemplatePK;
}
public String getDocFileName() {
return docFileName;
}
public void setDocFileName(String docFileName) {
this.docFileName = docFileName;
}
public String getDocType() {
return docType;
}
public void setDocType(String docType) {
this.docType = docType;
}
public byte[] getDocSrc() {
return docSrc;
}
public void setDocSrc(byte[] docSrc) {
this.docSrc = docSrc;
}
public Date getModifyTime() {
return modifyTime;
}
public void setModifyTime(Date modifyTime) {
this.modifyTime = modifyTime;
}
public String getModifyEmp() {
return modifyEmp;
}
public void setModifyEmp(String modifyEmp) {
this.modifyEmp = modifyEmp;
}
@Override
public String toString() {
return "DTPdfTemplate [dtPdfTemplatePK=" + dtPdfTemplatePK + ", docFileName=" + docFileName + ", docType="
+ docType + ", docSrc=" + Arrays.toString(docSrc) + ", modifyTime=" + modifyTime + ", modifyEmp="
+ modifyEmp + "]";
}
}
3.DTPdfColPK.java
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class DTPdfColPK implements Serializable {
@Column(name = "kind")
private int kind;
@Column(name = "colSeqno")
private int colSeqno;
public DTPdfColPK() {
}
public DTPdfColPK(int kind, int colSeqno) {
super();
this.kind = kind;
this.colSeqno = colSeqno;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + colSeqno;
result = prime * result + kind;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DTPdfColPK other = (DTPdfColPK) obj;
if (colSeqno != other.colSeqno)
return false;
if (kind != other.kind)
return false;
return true;
}
public int getKind() {
return kind;
}
public void setKind(int kind) {
this.kind = kind;
}
public int getColSeqno() {
return colSeqno;
}
public void setColSeqno(int colSeqno) {
this.colSeqno = colSeqno;
}
@Override
public String toString() {
return "DTPdfColPK [kind=" + kind + ", colSeqno=" + colSeqno + "]";
}
}
4.DTPdfCol.java
import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "DTPdfCol")
public class DTPdfCol implements Serializable {
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(
name = "kind",
column = @Column(name = "kind")),
@AttributeOverride(
name = "commSeqno",
column = @Column(name = "commSeqno"))
})
protected DTPdfColPK dtPdfColPK;
@Column(name = "colName")
protected String colName;
@Column(name = "colDesc")
protected String colDesc;
@Column(name = "testVal")
protected String testVal;
@Column(name = "modifyTime")
protected Date modifyTime;
@Column(name = "modifyEmp")
protected String modifyEmp;
public DTPdfCol() {
}
public DTPdfCol(DTPdfColPK dtPdfColPK) {
super();
this.dtPdfColPK = dtPdfColPK;
}
public DTPdfCol(DTPdfColPK dtPdfColPK, String colName, String colDesc, String testVal, Date modifyTime,
String modifyEmp) {
super();
this.dtPdfColPK = dtPdfColPK;
this.colName = colName;
this.colDesc = colDesc;
this.testVal = testVal;
this.modifyTime = modifyTime;
this.modifyEmp = modifyEmp;
}
public DTPdfColPK getDtPdfColPK() {
return dtPdfColPK;
}
public void setDtPdfColPK(DTPdfColPK dtPdfColPK) {
this.dtPdfColPK = dtPdfColPK;
}
public String getColName() {
return colName;
}
public void setColName(String colName) {
this.colName = colName;
}
public String getColDesc() {
return colDesc;
}
public void setColDesc(String colDesc) {
this.colDesc = colDesc;
}
public String getTestVal() {
return testVal;
}
public void setTestVal(String testVal) {
this.testVal = testVal;
}
public Date getModifyTime() {
return modifyTime;
}
public void setModifyTime(Date modifyTime) {
this.modifyTime = modifyTime;
}
public String getModifyEmp() {
return modifyEmp;
}
public void setModifyEmp(String modifyEmp) {
this.modifyEmp = modifyEmp;
}
@Override
public String toString() {
return "DTPdfCol [dtPdfColPK=" + dtPdfColPK + ", colName=" + colName + ", colDesc=" + colDesc + ", testVal="
+ testVal + ", modifyTime=" + modifyTime + ", modifyEmp=" + modifyEmp + "]";
}
}
三、hibernate sql
1.public DTPdfTemplate retriveDTPdfTemplate(int kind, int commSeqno): 取得套表的word原始檔
@Override
@Transactional(readOnly=true)
public List retriveDTPdfTemplate(int kind) {
Session session = getSession();
try {
Query query = session.createQuery(
" FROM DTPdfTemplate c WHERE kidn = :Kind Order By commSeqno ASC");
query.setParameter("Kind", kind);
List dtPdfTemplateList = query.list();
return dtPdfTemplateList;
} catch (Exception e) {
logger.error(e);
return null;
} finally {
if (session != null && session.isOpen() == true)
session.close();
}
}
2.public List retriveDTPdfCol(int kind): 取得套表功能變數欄位對應
@Override
@Transactional(readOnly=true)
public List retriveDTPdfCol(int kind) {
Session session = getSession();
try {
Query query = session.createQuery(
" FROM DTPdfCol c WHERE kind = :Kind");
query.setParameter("Kind", kind);
List dtPdfColList = query.list();
return dtPdfColList;
} catch (Exception e) {
logger.error(e);
return null;
} finally {
if (session != null && session.isOpen() == true)
session.close();
}
}
四、其它參數class
1.PDFTemplateKind.java : 套表類型參數值
public enum PDFTemplateKind {
ProductDesc(1, "檔案1") ,
TradeConfirm(2, "檔案2"),
NewTrade(3, "檔案3"),
ExpireTrade(4, "檔案4"),
ELNExpireNotice(5 , "檔案5", "檔案5-A"),
PGNExpireNotice(6 , "檔案5", "檔案5-B"),
ELNEarlyTerminate(7 , "檔案7", "檔案7-A"),
PGNEarlyTerminate(8 , "檔案7", "檔案7-B");
private int id;
private String desc;
private String title;
private PDFTemplateKind(int id, String desc) {
this.id = id;
this.desc = desc;
this.title = desc;
}
private PDFTemplateKind(int id, String desc, String title) {
this.id = id;
this.desc = desc;
this.title = title;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getDesc() {
return desc;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
2.DTPdfShowItem.java : 欲呈現的資料
public class DTPdfShowItem {
private int kind;
private int tradeSeqno;
private int mentionSeqno; //kind = 4 ~ 8
//以下新增各property...
....
public DTPdfShowItem(int kind, int tradeSeqno, int mentionSeqno) {
super();
this.kind = kind;
this.tradeSeqno = tradeSeqno;
this.mentionSeqno = mentionSeqno;
}
//依欄位設定set、get function
...
@Override
public String toString() {
return "DTPdfShowItem [kind=" + kind + ..... //依上方property設定
}
五、DTPdfShowAction.java (主要程式邏輯)
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import com.lowagie.text.FontFactory;
import fr.opensagres.xdocreport.converter.ConverterTypeTo;
import fr.opensagres.xdocreport.converter.ConverterTypeVia;
import fr.opensagres.xdocreport.converter.Options;
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
public class DTPdfShowAction extends BaseAction {
private int kind;
private int tradeSeqno;
private int mentionSeqno;
public DTPdfShowAction() {
super();
}
public int getKind() {
return kind;
}
public void setKind(int kind) {
this.kind = kind;
}
public int getTradeSeqno() {
return tradeSeqno;
}
public void setTradeSeqno(int tradeSeqno) {
this.tradeSeqno = tradeSeqno;
}
public int getMentionSeqno() {
return mentionSeqno;
}
public void setMentionSeqno(int mentionSeqno) {
this.mentionSeqno = mentionSeqno;
}
public String execute() throws Exception {
//1.判斷傳入參數
if (kind > 8) {
logger.error("No Docment match");
response.getWriter().println("No Docment match");
return NONE;
}
if (kind == PDFTemplateKind.ProductDesc.getId() ||
kind == PDFTemplateKind.TradeConfirm.getId() ||
kind == PDFTemplateKind.NewTrade.getId()) {
if (tradeSeqno <= 0) {
logger.error("tradeSeqno error");
response.getWriter().println("tradeSeqno error");
return NONE;
}
} else {
if (mentionSeqno <= 0) {
logger.error("mentionSeqno error");
response.getWriter().println("mentionSeqno error");
return NONE;
}
}
//2.取得此筆資料相關訊息
DTServiceEntry dtServiceEntry = new DTServiceEntry();
DTPdfShowItem dtPdfShowItem = new DTPdfShowItem(kind, tradeSeqno, mentionSeqno);
boolean bOK = retriveSourceData(dtServiceEntry, dtPdfShowItem);
if (bOK == false) {
logger.error("retrive Source Data error");
response.getWriter().println("retrive Source Data error");
return NONE;
}
logger.info(dtPdfShowItem);
//3.取得此筆資料明細
List dtPdfColList = dtServiceEntry.retriveDTPdfCol(kind);
if (dtPdfColList == null || dtPdfColList.size() <= 0) {
logger.error("retrive DTPdfCol error");
response.getWriter().println("retrive DTPdfCol error");
return NONE;
}
bOK = mappingColData(dtServiceEntry, dtPdfShowItem, dtPdfColList);
if (bOK == false) {
logger.error("retrive Col Data error");
response.getWriter().println("retrive Col Data error");
return NONE;
}
logger.info(dtPdfColList);
int commSeqno = (kind == PDFTemplateKind.ProductDesc.getId() || kind == PDFTemplateKind.TradeConfirm.getId()) ? dtPdfShowItem.getDtInqPrice().getCommSeqno() : 0;
DTPdfTemplate dtPdfTemplate = dtServiceEntry.retriveDTPdfTemplate(kind, commSeqno);
if (dtPdfTemplate != null) {
try {
// 1) Load Docx file by filling Velocity template engine and cache
InputStream in = new ByteArrayInputStream(dtPdfTemplate.getDocSrc());
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(
in, TemplateEngineKind.Velocity);
// 2) Create context Java model
IContext context = report.createContext();
//DTPdfProject project = new DTPdfProject("PDF範例-" + dtPdfTemplate.getDocFileName());
DTPdfProject project = new DTPdfProject(dtPdfShowItem.getPdfFileName());
context.put("project", project);
for (DTPdfCol dtPdfCol : dtPdfColList) {
logger.info(dtPdfCol);
context.put(dtPdfCol.getColName(), dtPdfCol.getTestVal());
}
// 3) Generate report by merging Java model with the Docx
ByteArrayOutputStream outPdf = new ByteArrayOutputStream();
PdfOptions pdfOptions = PdfOptions.create();
FontFactory.registerDirectory(application.getRealPath("/") + "WEB-INF" + File.separator + "classes" + File.separator + "fonts" + File.separator);
Options options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF).subOptions(pdfOptions);
report.convert(context, options, outPdf);
// 4) 顯示檔案
String docFileName = java.net.URLEncoder.encode(dtPdfShowItem.getPdfFileName(), "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=".concat(docFileName));
response.setContentType(getContentType("pdf"));
OutputStream out = response.getOutputStream();
out.write(outPdf.toByteArray());
out.close();
} catch (IOException e1) {
logger.error(e1);
} catch (XDocReportException e2) {
logger.error(e2);
}
} else {
logger.error("No Docment - kind : " + kind + ", commSeqno : " + commSeqno);
response.getWriter().println("No Docment");
}
return NONE;
}
/**
* 取得相關資料
* @param dtPdfShowItem
* @return
*/
private boolean retriveSourceData(DTServiceEntry dtServiceEntry, DTPdfShowItem dtPdfShowItem) {
//mapping 實際資料至dtPdfShowItem,請自行撰寫,此處省略
...
return true;
}
/**
* 取得此筆資料明細
* @param dtServiceEntry
* @param dtPdfShowItem
* @param dtPdfColList
* @return
*/
private boolean mappingColData(DTServiceEntry dtServiceEntry, DTPdfShowItem dtPdfShowItem,
List dtPdfColList) {
//依pdf版型對應,取得套表相關對應值,於對應mappingColData_[1~n]函數實做
if (dtPdfShowItem.getKind() == PDFTemplateKind.ProductDesc.getId()) {
return mappingColData_1(dtServiceEntry, dtPdfShowItem, dtPdfColList);
} else if (dtPdfShowItem.getKind() == PDFTemplateKind.TradeConfirm.getId()) {
return mappingColData_2(dtServiceEntry, dtPdfShowItem, dtPdfColList);
} else if (dtPdfShowItem.getKind() == PDFTemplateKind.NewTrade.getId()) {
return mappingColData_3(dtServiceEntry, dtPdfShowItem, dtPdfColList);
} else if (dtPdfShowItem.getKind() == PDFTemplateKind.ExpireTrade.getId()) {
return mappingColData_4(dtServiceEntry, dtPdfShowItem, dtPdfColList);
} else if (dtPdfShowItem.getKind() == PDFTemplateKind.ELNExpireNotice.getId()) {
return mappingColData_5(dtServiceEntry, dtPdfShowItem, dtPdfColList);
} else if (dtPdfShowItem.getKind() == PDFTemplateKind.PGNExpireNotice.getId()) {
return mappingColData_6(dtServiceEntry, dtPdfShowItem, dtPdfColList);
} else if (dtPdfShowItem.getKind() == PDFTemplateKind.ELNEarlyTerminate.getId()) {
return mappingColData_7(dtServiceEntry, dtPdfShowItem, dtPdfColList);
} else if (dtPdfShowItem.getKind() == PDFTemplateKind.PGNEarlyTerminate.getId()) {
return mappingColData_8(dtServiceEntry, dtPdfShowItem, dtPdfColList);
}
return true;
}
/**
* @param dtServiceEntry
* @param dtPdfShowItem
* @param dtPdfColList
* @return
*/
private boolean mappingColData_1(DTServiceEntry dtServiceEntry, DTPdfShowItem dtPdfShowItem,
List dtPdfColList) {
for (DTPdfCol dtPdfCol : dtPdfColList) {
String colName = dtPdfCol.getColName();
if (colName.compareToIgnoreCase("trade.targetName") == 0)
dtPdfCol.setTestVal(dtPdfShowItem.getDtInqPrice().getTargetName());
else if (colName.compareToIgnoreCase("trade.riskLevel") == 0)
dtPdfCol.setTestVal("RR" + Integer.toString(dtPdfShowItem.getDtInqPrice().getCommRiskLevel()));
//依實際資料做mapping
...
} else {
dtPdfCol.setTestVal("");
}
}
return true;
}
/**
* @param dtServiceEntry
* @param dtPdfShowItem
* @param dtPdfColList
* @return
*/
private boolean mappingColData_2(DTServiceEntry dtServiceEntry, DTPdfShowItem dtPdfShowItem,
List dtPdfColList) {
for (DTPdfCol dtPdfCol : dtPdfColList) {
String colName = dtPdfCol.getColName();
if (colName.compareToIgnoreCase("client.name") == 0)
dtPdfCol.setTestVal(dtPdfShowItem.getClientName());
else if (colName.compareToIgnoreCase("client.addr") == 0)
dtPdfCol.setTestVal(dtPdfShowItem.getClientAddr());
//依實際資料做mapping
...
} else {
dtPdfCol.setTestVal("");
}
}
return true;
}
/**
* @param dtServiceEntry
* @param dtPdfShowItem
* @param dtPdfColList
* @return
*/
private boolean mappingColData_3(DTServiceEntry dtServiceEntry, DTPdfShowItem dtPdfShowItem,
List dtPdfColList) {
DRServiceEntry drServiceEntry = new DRServiceEntry();
for (DTPdfCol dtPdfCol : dtPdfColList) {
String colName = dtPdfCol.getColName();
if (colName.compareToIgnoreCase("trade.seqno") == 0) {
String value = dtPdfShowItem.getDtTrade().getProdSeqno();
dtPdfCol.setTestVal((value == null) ? "尚未產出" : value);
} else if (colName.compareToIgnoreCase("trade.targetId") == 0)
dtPdfCol.setTestVal(dtPdfShowItem.getDtInqPrice().getTargetId());
//依實際資料做mapping
...
else {
dtPdfCol.setTestVal("");
}
}
return true;
}
/**
* @param dtServiceEntry
* @param dtPdfShowItem
* @param dtPdfColList
* @return
*/
private boolean mappingColData_4(DTServiceEntry dtServiceEntry, DTPdfShowItem dtPdfShowItem,
List dtPdfColList) {
for (DTPdfCol dtPdfCol : dtPdfColList) {
String colName = dtPdfCol.getColName();
if (colName.compareToIgnoreCase("trade.cateId") == 0)
dtPdfCol.setTestVal(dtPdfShowItem.getMentionTypeDesc());
//依實際資料做mapping
...
else {
dtPdfCol.setTestVal("");
}
}
return true;
}
/**
* @param dtServiceEntry
* @param dtPdfShowItem
* @param dtPdfColList
* @return
*/
private boolean mappingColData_5(DTServiceEntry dtServiceEntry, DTPdfShowItem dtPdfShowItem,
List dtPdfColList) {
for (DTPdfCol dtPdfCol : dtPdfColList) {
String colName = dtPdfCol.getColName();
if (colName.compareToIgnoreCase("client.name") == 0)
dtPdfCol.setTestVal(dtPdfShowItem.getClientName());
//依實際資料做mapping
...
} else {
dtPdfCol.setTestVal("");
}
}
return true;
}
/**
* @param dtServiceEntry
* @param dtPdfShowItem
* @param dtPdfColList
* @return
*/
private boolean mappingColData_6(DTServiceEntry dtServiceEntry, DTPdfShowItem dtPdfShowItem,
List dtPdfColList) {
for (DTPdfCol dtPdfCol : dtPdfColList) {
String colName = dtPdfCol.getColName();
if (colName.compareToIgnoreCase("client.name") == 0)
dtPdfCol.setTestVal(dtPdfShowItem.getClientName());
//依實際資料做mapping
...
} else {
dtPdfCol.setTestVal("");
}
}
return true;
}
/**
* @param dtServiceEntry
* @param dtPdfShowItem
* @param dtPdfColList
* @return
*/
private boolean mappingColData_7(DTServiceEntry dtServiceEntry, DTPdfShowItem dtPdfShowItem,
List dtPdfColList) {
for (DTPdfCol dtPdfCol : dtPdfColList) {
String colName = dtPdfCol.getColName();
if (colName.compareToIgnoreCase("client.name") == 0)
dtPdfCol.setTestVal(dtPdfShowItem.getClientName());
//依實際資料做mapping
...
} else {
dtPdfCol.setTestVal("");
}
}
return true;
}
/**
* @param dtServiceEntry
* @param dtPdfShowItem
* @param dtPdfColList
* @return
*/
private boolean mappingColData_8(DTServiceEntry dtServiceEntry, DTPdfShowItem dtPdfShowItem,
List dtPdfColList) {
for (DTPdfCol dtPdfCol : dtPdfColList) {
String colName = dtPdfCol.getColName();
if (colName.compareToIgnoreCase("client.name") == 0)
dtPdfCol.setTestVal(dtPdfShowItem.getClientName());
//依實際資料做mapping
...
} else {
dtPdfCol.setTestVal("");
}
}
return true;
}
}






