你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 网络与通信
在线生成Word文档的实现与应用(三)
 

1 开发过程

1.1 Web端在线文档生成桩模块

1.1.1 在线文档生成桩模块头部定义

在线文档生成的桩模块是JSP页面,其需要调用后台的文档生成器对象,所以需要在JSP头部对所包含的库进行定义,JSP页面的头部定义如代码1所示。

代码1 在线文档生成桩模块的头部定义

文件名:stub.jsp

1

2

3

4

5

6

7

<%@ page language="java" import="java.io.*,foolstudio.bi.*" pageEncoding="gb2312"%>

<%

       final String path = request.getContextPath();

       final String basePath = request.getScheme()+"://"+request.getServerName()+

                                          ":"+request.getServerPort()+path+"/";

       final String baseRealPath = this.getServletContext().getRealPath("/");

%>

    需要注意的是,包含代码1中“foolstudio.bi”包的Jar文档需要分发在当前域的“WEB-INF\lib”文件夹中,另外JACOB相关的库文件也必须分发在该文件夹中。

1.1.2 在线文档生成桩模块的主体

代码2中是在线文档生成桩模块的主体代码,其中主要是调用后台的文档生成器对象,生成目标文档,并将其URL推送到前端页面。

代码2 在线文档生成桩模块的主体代码

文件名:stub.jsp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<%

       String template = request.getParameter("template");

 

       if(template == null) {

              out.println("<p>无效的文档模板!</p>");

              return;

       }

      

       response.setCharacterEncoding("gb2312");

       response.setContentType("text/html");

       //

       String templatePath = baseRealPath + "templates/";

       String outputPath = baseRealPath + "temp/";

      

       DocBuilder builder = new DocBuilder(template, baseRealPath);

       builder.saveAs(templatePath, outputPath);

      

       String outputRealFile = outputPath+builder.getOutput();

       String outputFile = basePath+"temp/"+builder.getOutput();

      

       File aFile = new File(outputRealFile);

       if(aFile.exists() ) {

              out.println("<p>Word报告生成成功!</p>");

              out.println("<p><a href=\"" + outputFile + "\">查看或下载</a></p>");

       out.println("<p><a href=\"#\" onclick=\"window.close();\">关闭本窗体</a></p>");

       }

       else {

              out.println("<p>抱歉!报告生成失败,请与管理员联系!</p>");

       out.println("<p><a href=\"#\" onclick=\"window.close();\">关闭本窗体</a></p>");

       }

%>

 

1.2 文档生成器

1.2.1 配置文件

代码3是文档生成器所依赖的配置文件,其中定义了数据库的连接信息、文档模板与数据源的对应关系和数据源的定义。

代码3 配置文件

文件名:db.properties

1

2

3

4

5

6

7

URL=jdbc:oracle:thin:@localhost:1521/FOO

USER=foo

PASSWD=********

staff_ds=ds1

ds1=select STA_ID,STA_XM,STA_XB,to_char(STA_SR,'yyyy-mm-dd') STA_SR,

to_char(STA_RZRQ,'yyyy-mm-dd') STA_RZRQ,

STA_ZGXL,STA_BYXX,STA_BM,STA_GW from tab_staff

 

1.2.2 文档生成器初始化

代码4是文档生成器初始化代码,其主要内容是根据文档模板获取对应的数据源列表,并将所有数据源中的数据读出并存放到数据集容器中。

代码4 初始化文档生成器

文件名:DocBuilder.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

public DocBuilder(String templateId, String ctxPath) {

       this.mTemplateId = templateId;

      

       Properties props = new Properties();

       String dsList = null;

       try {

              props.load(new FileInputStream(ctxPath+DB_SETTING));

              dsList = props.getProperty(templateId+"_"+DS_PREFIX);

       } catch (FileNotFoundException e) {

              FooDebug.getInstance().println(e.getMessage());

              return;

       } catch (IOException e) {

              FooDebug.getInstance().println(e.getMessage());

              return;

       }     

      

       if(dsList == null) {

              FooDebug.getInstance().println("无效的文档模板!");

              return;

       }            

      

       //构造结果集容器

       this.mResuleSet = new HashMap<String,ArrayList<ArrayList<String>>>();

      

       try {

              //初始化结果集容器

              initResultSet(dsList, props);

       } catch (SQLException e) {

              e.printStackTrace();

       }

}

    代码4中,存放结果集的容器是一个以结果集名为键,以二维数组为值的散列容器(第23行),主要是考虑到一个文档模板中可能包含多个结果集。

1.2.3 初始化结果集容器

初始化结果集容器主要内容是根据数据源的定义从后台数据库中提取数据并填充到结果集容器中,代码5是初始化结果集容器的主要代码。

代码5 初始化结果集容器

文件名:DocBuilder.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

//初始化结果集

private void initResultSet(String dsList, Properties props) throws SQLException {

       //获取数据库配置

       final String url = props.getProperty("URL");

       final String user = props.getProperty("USER");

       final String passwd = props.getProperty("PASSWD");

      

       if(url==null || user==null || passwd==null) {

              return;

       }            

       //判断Oracle驱动是否存在

       if(FooDb.getInstance().isFoundOracleDriver()==false) {

              return;

       }            

      

       Connection conn = FooDb.getInstance().getConnector(url, user, passwd);

       Statement stat = FooDb.getInstance().getQueryStat(conn);

       //分割所有数据源

       final String[] dss = dsList.split(",");      

       //遍历所有数据源

       for(int i = 0; i < dss.length; ++i) {

              String sql = props.getProperty(dss[i]);

             

              ResultSet rs = FooDb.getInstance().execQuery(stat, sql);

              int colsCount = FooDb.getInstance().getColsCount(rs);

              //定义单数据源的记录行

              ArrayList<ArrayList<String>> rows = new ArrayList<ArrayList<String>>();

              //表头各列

              /*

              ArrayList<String> header = new ArrayList<String>();

              for(int i = 1; i <= colsCount; ++i) {

                     header.add(FooDb.getInstance().getColName(rs, i));

              }

              rows.add(header);

              */

              //遍历各行

              while(rs.next()) {

                     ArrayList<String> row = new ArrayList<String>();

                     for(int j = 1; j <= colsCount; ++j) {

                            row.add(rs.getString(j));

                     }

                     rows.add(row);

              }

              FooDb.getInstance().closeRs(rs);

             

              //将单个结果集存入到结果集容器

              this.mResuleSet.put(dss[i], rows);              

       }

       //关闭语句对象和数据库连接

       FooDb.getInstance().closeStat(stat);

       FooDb.getInstance().closeConn(conn);

}

       代码5中,文档解析器分割指定文档模板所对应的数据源列表(第19行),然后逐一读取数据源中的记录行(从第21行到第48行),最后将单个结果集存入到结果集容器中(第47行)。

       这种首先将所有数据源的数据加载到内存的方式可能会对系统内存的占用造成一定的压力,但是对于后面的数据检索而言,会显著提高检索效率。对于此处需要开发者按照实际的情况进行权衡。

 

 

  推荐精品文章

·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 
·2023年7月目录
·2023年6月目录 
·2023年5月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089