好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java 实现word模板转为pdf

1. pom相关依赖

工具poi-tl (操作word文档模板) + jacob (将操作后的word模板转为pdf)

?

1

2

3

4

5

6

<!-- poi-tl的pom依赖 -->

< dependency >

   < groupId >com.deepoove</ groupId >

   < artifactId >poi-tl</ artifactId >

   < version >1.9.1</ version >

</ dependency >

?

1

2

3

4

5

6

7

8

<!-- jacob的pom依赖(需自行导入.jar包) -->

< dependency >

   < groupId >com.jacob</ groupId >

   < artifactId >jacob</ artifactId >

   < version >1.17</ version >

   < scope >system</ scope >

   < systemPath >${project.basedir}/src/main/resources/lib/jacob.jar</ systemPath >

</ dependency >

2. 对word模板进行插入数据操作

使用poi-tl操作word需要创建一个用于向word插入数据的Map<String, Object>集合, word模板中标签格式为"{{标签}}", 其中标签内容为Map<String, Object> 的key.

?

1

2

3

4

5

6

7

8

9

10

// 项目根路径

String abPath = new File( "" ).getAbsolutePath() + "/src/main/resources" ;

// 创建用于插入数据的Map

Map<String, Object> map = new HashMap<>();

map.put(<k>, <v>);

...

// 填充word文档

XWPFTemplate template = XWPFTemplate测试数据pile(abPath + "<模板路径>" ).render(map);

// 输出文档

template.writeAndClose( new FileOutPutStream( "<输出路径>" ));

3. 对word模板的表格执行插入数据操作(动态表格)

使用poi-tl操作word的表格,动态的插入数据,需要用到poi-tl的可选插件进行自定义渲染策略, 首先在word需要操作的表格中的任意单元格添加标签[{{标签}}]

自定义渲染策略

?

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

/**

  * 自定义渲染策略

  *

  * @author

  */

public class DetailTablePolicy extends DynamicTableRenderPolicy {

   // 表格起始行行数

   int tableStartRow = 1 ;

 

   /**

    * 自定义渲染策略

    *

    * @data 传入的封装好的数据

    */

   @Override

   public void render(XWPFTable table, Object data) throws Exception {

     // 如果数据为空,直接返回

     if ( null == data) return ;

     // 封装数据List的数据封装对象

     NdrwhkhzbData detailData = (NdrwhkhzbData) data;

         // 获取当前列表行高

     int height = table.getRow( 2 ).getHeight();

     // 从封装对象中获取数据集合

     List<RowRenderData> datas = detailData.getNdrwhkhzbs();

     if ( null != datas) {

       // 循环移除空白表格中数据数量的空白行

       for ( int i = 1 ; i < datas.size() + 2 ; i++) {

         table.removeRow(i);

       }

       // 循环插入数据

       for ( int i = 0 ; i < datas.size(); i++) {

         // 新增一行空白行

         XWPFTableRow insertNewTableRow = table.insertNewTableRow(tableStartRow);

         // 设置行高

         insertNewTableRow.setHeight(height);

         // 循环添加单元格(4为每行单元格数量)

         for ( int j = 0 ; j < 4 ; j++) {

           insertNewTableRow.createCell();

         }

         // 填充表格

         TableRenderPolicy.Helper.renderRow(table.getRow(tableStartRow), datas.get(i));

       }

     }

   }

}

把自定义渲染策略当做工具类, 在主逻辑中直接配置使用

?

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

   /**

  * 操作年度任务和考核指标表

  *

  * @throws IOException 输入输出流异常

  */

private void createNdrwhkhzb(Integer uid, String dirPath) throws IOException {

   PageData datas = new PageData();

   NdrwhkhzbData detailTable = new NdrwhkhzbData();

   List<RowRenderData> nds = new ArrayList<>();

   // 根据uid查询年度任务和考核指标数据

   List<NdrwhkhzbEntity> list = ndrwhkhzbService.selectNdrwhkhzbByUid(uid);

   for (NdrwhkhzbEntity ndrwhkhzbEntity : list) {

     RowRenderData rrd = Rows.of(ndrwhkhzbEntity.getNd(), ndrwhkhzbEntity.getNdrw(), ndrwhkhzbEntity.getNdkhzb()

         , ndrwhkhzbEntity.getZyrwdsjjd()).center().create();

     nds.add(rrd);

   }

   detailTable.setNdrwhkhzbs(nds);

   datas.setNdrwhkhzbData(detailTable);

 

   // 配置表格

   Configure config = Configure.builder().bind( "detail_table" , new DetailTablePolicy()).build();

   // 调用渲染策略进行填充

   XWPFTemplate template =

       XWPFTemplate测试数据pile(dirPath + "/" + uid + "_Complete.docx" , config).render(datas);

   // 写入表格中

   template.writeToFile(dirPath + "/" + uid + "_Complete.docx" );

}

用到的一些实体类

?

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

// PageData

public class PageData {

   @Name ( "detail_table" )

   private NdrwhkhzbData ndrwhkhzbData;

 

   public NdrwhkhzbData getNdrwhkhzbData() {

     return ndrwhkhzbData;

   }

 

   public void setNdrwhkhzbData(NdrwhkhzbData ndrwhkhzbData) {

     this .ndrwhkhzbData = ndrwhkhzbData;

   }

}

 

// NdrwhkhzbData

public class NdrwhkhzbData {

   private List<RowRenderData> ndrwhkhzbs;

 

   public List<RowRenderData> getNdrwhkhzbs() {

     return ndrwhkhzbs;

   }

 

   public void setNdrwhkhzbs(List<RowRenderData> ndrwhkhzbs) {

     this .ndrwhkhzbs = ndrwhkhzbs;

   }

}

4. 将编辑好的Word转为pdf格式(jacob)

这里将word转为pdf时需要用到jacob, 这里需要将jacob的dll文件放到jdk和jre的bin目录下, 下载的jacob中dll文件一般为两个版本, X86为32位, X64为64位, 根据自己安装的jdk版本添加所对应的dll文件

?

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

/*

   * 将 .docx 转换为 .pdf

   */

ActiveXComponent app = null ;

String wordFile = dirPath + "/" + uid + "_Complete.docx" ;

String pdfFile = dirPath + "/" + dirName + ".pdf" ;

 

System.out.println( "开始转换..." );

// 开始时间

long start = System.currentTimeMillis();

try {

   // 打开word

   app = new ActiveXComponent( "Word.Application" );

   // 设置word不可见,很多博客下面这里都写了这一句话,其实是没有必要的,因为默认就是不可见的,如果设置可见就是会打开一个word文档,对于转化为pdf明显是没有必要的

   //app.setProperty("Visible", false);

   // 获得word中所有打开的文档

   Dispatch documents = app.getProperty( "Documents" ).toDispatch();

   System.out.println( "打开文件: " + wordFile);

   // 打开文档

   Dispatch documentP = Dispatch.call(documents, "Open" , wordFile, false , true ).toDispatch();

   // 如果文件存在的话,不会覆盖,会直接报错,所以我们需要判断文件是否存在

   File target = new File(pdfFile);

   if (target.exists()) {

     target.delete();

   }

   System.out.println( "另存为: " + pdfFile);

   // 另存为,将文档报错为pdf,其中word保存为pdf的格式宏的值是17

   Dispatch.call(documentP, "SaveAs" , pdfFile, 17 );

   // 关闭文档

   Dispatch.call(documentP, "Close" , false );

   // 结束时间

   long end = System.currentTimeMillis();

   System.out.println( "转换成功,用时:" + (end - start) + "ms" );

} catch (Exception e) {

   e.getMessage();

   System.out.println( "转换失败" + e.getMessage());

} finally {

   // 关闭office

   app.invoke( "Quit" , 0 );

}

5. 通过lo流将生成好的文件传到浏览器下载

?

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

/*

  * 下载pdf

  */

String fileName = dirName + ".pdf" ;

File file = new File(dirPath + "/" + fileName);

if (file.exists()) {

   BufferedInputStream bis = null ;

   FileInputStream fis = null ;

   try {

     response.setHeader( "Content-disposition" , "attachment; filename=" + fileName);

     byte [] buff = new byte [ 2048 ];

     fis = new FileInputStream(file);

     bis = new BufferedInputStream(fis);

     OutputStream os = response.getOutputStream();

     int i = bis.read(buff);

     while (i != - 1 ) {

       os.write(buff, 0 , i);

       i = bis.read(buff);

     }

     os.close();

   } catch (Exception e) {

     e.printStackTrace();

   } finally {

     assert fis != null ;

     fis.close();

     assert bis != null ;

     bis.close();

   }

}

6. 最后的Controller整体代码

?

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

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

package org.example.controller;

 

import com.deepoove.poi.XWPFTemplate;

import com.deepoove.poi.config.Configure;

import com.deepoove.poi.data.Includes;

import com.deepoove.poi.data.RowRenderData;

import com.deepoove.poi.data.Rows;

import com.jacob.activeX.ActiveXComponent;

import com.jacob测试数据.Dispatch;

import org.example.entity.*;

import org.example.service.*;

import org.example.utils.DetailTablePolicy;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Scope;

import org.springframework.stereotype.Controller;

import org.springframework.util.DigestUtils;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

 

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import java.io.*;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

/**

  * 创建pdf控制器

  *

  * @author: yoojyn

  * @data: 2021/1/11

  */

@Controller

@RequestMapping ( "/createPdfController" )

public class CreatePdfController {

   @Autowired

   private IKtfmService ktfmService;

   @Autowired

   private IKtjbxxService ktjbxxService;

   @Autowired

   private IKtbyxfxService ktbyxfxService;

   @Autowired

   private IZtmbhkhzbService ztmbhkhzbService;

   @Autowired

   private INdrwhkhzbService ndrwhkhzbService;

   @Autowired

   private IKtjfysjsmService ktjfysjsmService;

   @Autowired

   private IXjxhkxxfxService xjxhkxxfxService;

 

   /**

    * 生成word文件

    *

    * @param session 作用域

    */

   @Scope ( "prototype" )

   @ResponseBody

   @RequestMapping ( "/createPdf" )

   public void createPdf(HttpSession session, HttpServletResponse response) {

     // 获取当前用户id

     Userinfo loginedUser = (Userinfo) session.getAttribute( "loginedUser" );

     Integer uid = loginedUser.getUid();

     String dirName = DigestUtils.md5DigestAsHex((uid + "_国家重大专项任务合同申报" ).getBytes());

     String dirPath = "D:/" + dirName;

     String abPath = new File( "" ).getAbsolutePath() + "/src/main/resources" ;

 

     try {

       // 创建用于存储中间文件的文件夹

       new File(dirPath).mkdirs();

       // 创建用于存储数据的map集合

       Map<String, Object> map = new HashMap<>();

       // 获取封面数据

       createKtfm(uid, map);

       // 获取基本信息数据

       createJbxx(uid, map);

       // 获取必要性分析

       createByxfx(uid, map);

       // 获取总体目标和考核指标

       createZtmbhkhzb(uid, map);

       // 获取经费预算及说明

       createJfysjsm(uid, map);

       // 查询附件

       XjxhkxxfxEntity xjxhkxxfxEntity = xjxhkxxfxService.selectXjxhkxxfxByUid(uid);

       // 设置下一步处理表格要用到的标签

       map.put( "page9" ,

           Includes.ofLocal(abPath + "/static/file/upload/" + xjxhkxxfxEntity.getFilename()).create());

       map.put( "detail_table" , "{{detail_table}}" );

       // 填充文档

       XWPFTemplate template = XWPFTemplate测试数据pile(abPath + "/static/file/moban/moban.docx" ).render(map);

       // 输出文档

       template.writeAndClose( new FileOutputStream(dirPath + "/" + uid + "_Complete.docx" ));

       // 操作年度任务和考核指标表

       createNdrwhkhzb(uid, dirPath);

     } catch (IOException e) {

       e.printStackTrace();

     }

 

     try {

       /*

        * 将 .docx 转换为 .pdf

        */

       ActiveXComponent app = null;

       String wordFile = dirPath + "/" + uid + "_Complete.docx";

       String pdfFile = dirPath + "/" + dirName + ".pdf";

 

       System.out.println("开始转换...");

       // 开始时间

       long start = System.currentTimeMillis();

       try {

         // 打开word

         app = new ActiveXComponent("Word.Application");

         // 设置word不可见,很多博客下面这里都写了这一句话,其实是没有必要的,因为默认就是不可见的,如果设置可见就是会打开一个word文档,对于转化为pdf明显是没有必要的

         //app.setProperty("Visible", false);

         // 获得word中所有打开的文档

         Dispatch documents = app.getProperty("Documents").toDispatch();

         System.out.println("打开文件: " + wordFile);

         // 打开文档

         Dispatch documentP = Dispatch.call(documents, "Open", wordFile, false, true).toDispatch();

         // 如果文件存在的话,不会覆盖,会直接报错,所以我们需要判断文件是否存在

         File target = new File(pdfFile);

         if (target.exists()) {

           target.delete();

         }

         System.out.println("另存为: " + pdfFile);

         // 另存为,将文档报错为pdf,其中word保存为pdf的格式宏的值是17

         Dispatch.call(documentP, "SaveAs", pdfFile, 17);

         // 关闭文档

         Dispatch.call(documentP, "Close", false);

         // 结束时间

         long end = System.currentTimeMillis();

         System.out.println("转换成功,用时:" + (end - start) + "ms");

       } catch (Exception e) {

         e.getMessage();

         System.out.println("转换失败" + e.getMessage());

       } finally {

         // 关闭office

         app.invoke("Quit", 0);

       }

 

       /*

        * 下载pdf

        */

       String fileName = dirName + ".pdf";

       File file = new File(dirPath + "/" + fileName);

       if (file.exists()) {

         BufferedInputStream bis = null;

         FileInputStream fis = null;

         try {

           response.setHeader("Content-disposition", "attachment; filename=" + fileName);

           byte[] buff = new byte[2048];

           fis = new FileInputStream(file);

           bis = new BufferedInputStream(fis);

           OutputStream os = response.getOutputStream();

           int i = bis.read(buff);

           while (i != -1) {

             os.write(buff, 0, i);

             i = bis.read(buff);

           }

           os.close();

         } catch (Exception e) {

           e.printStackTrace();

         } finally {

           assert fis != null;

           fis.close();

           assert bis != null;

           bis.close();

         }

       }

     } catch (Exception e) {

       e.printStackTrace();

     } finally {

       delDir(new File(dirPath));

     }

   }

 

   /**

    * 删除文件夹

    *

    * @param file 文件夹对象

    */

   private void delDir(File file) {

     if (file.isFile()) {

       file.delete();

     }

     if (file.isDirectory()) {

       File[] files = file.listFiles();

       for (File f : files) {

         f.delete();

       }

       file.delete();

     }

   }

 

   /**

    * 储存经费预算及说明

    *

    * @param uid 用户id

    * @param map 储存数据的map集合

    */

   private void createJfysjsm(Integer uid, Map<String, Object> map) {

     // 根据用户编号查询经费预算及说明

     KtjfysjsmEntity ktjfysjsmEntity = ktjfysjsmService.getDatesByUid(uid);

     // 添加到map集合

     map.put("zjzyczzj", ktjfysjsmEntity.getZjzyczzj());

     map.put("zjdfczzj", ktjfysjsmEntity.getZjdfczzj());

     map.put("zjdwzczj", ktjfysjsmEntity.getZjdwzczj());

     map.put("zjqt", ktjfysjsmEntity.getZjqt());

   }

 

   /**

    * 操作年度任务和考核指标表

    *

    * @throws IOException 输入输出流异常

    */

   private void createNdrwhkhzb(Integer uid, String dirPath) throws IOException {

     PageData datas = new PageData();

     NdrwhkhzbData detailTable = new NdrwhkhzbData();

     List<RowRenderData> nds = new ArrayList<>();

     // 根据uid查询年度任务和考核指标数据

     List<NdrwhkhzbEntity> list = ndrwhkhzbService.selectNdrwhkhzbByUid(uid);

     for (NdrwhkhzbEntity ndrwhkhzbEntity : list) {

       RowRenderData rrd = Rows.of(ndrwhkhzbEntity.getNd(), ndrwhkhzbEntity.getNdrw(), ndrwhkhzbEntity.getNdkhzb()

           , ndrwhkhzbEntity.getZyrwdsjjd()).center().create();

       nds.add(rrd);

     }

     detailTable.setNdrwhkhzbs(nds);

     datas.setNdrwhkhzbData(detailTable);

 

     Configure config = Configure.builder().bind("detail_table", new DetailTablePolicy()).build();

     XWPFTemplate template =

         XWPFTemplate测试数据pile(dirPath + "/" + uid + "_Complete.docx", config).render(datas);

     template.writeToFile(dirPath + "/" + uid + "_Complete.docx");

   }

 

   /**

    * 储存总体目标和考核指标

    *

    * @param uid 用户id

    * @param map 储存数据的map集合

    */

   private void createZtmbhkhzb(Integer uid, Map<String, Object> map) {

     // 根据用户编号查询总体目标和考核指标

     ZtmbhkhzbEntity ztmbhkhzbEntity = ztmbhkhzbService.selectZtmbhkhzbByUid(uid);

     // 添加到map集合

     map.put("page6", ztmbhkhzbEntity.getZtmbhkhzb());

   }

 

   /**

    * 储存必要性分析数据

    *

    * @param uid 用户id

    * @param map 储存数据的map集合

    */

   private void createByxfx(Integer uid, Map<String, Object> map) {

     // 根据用户编号查询必要性分析数据

     KtbyxfxEntityWithBLOBs ktbyxfxEntity = ktbyxfxService.selectKtbyxfxByUid(uid);

     // 添加到map集合

     map.put("page5_ktyzx", ktbyxfxEntity.getKtyzx());

     map.put("page5_ktysfgc", ktbyxfxEntity.getKtysf());

     map.put("page5_ktyq", ktbyxfxEntity.getKtyq());

   }

 

   /**

    * 储存基本信息数据

    *

    * @param uid 用户编号

    * @param map 储存数据的map集合

    */

   private void createJbxx(Integer uid, Map<String, Object> map) {

     // 根据用户编号查询基本信息数据

     KcjbxxEntity kcjbxxEntity = ktjbxxService.selectKtjbxxByUid(uid);

     // 添加到map集合

     map.put("page3_ktmc", kcjbxxEntity.getKtmc());

     map.put("page3_ktmj", kcjbxxEntity.getKtmj());

     map.put("page3_yjwcsj", kcjbxxEntity.getYjwcsj());

     map.put("page3_kyhdlx", kcjbxxEntity.getKthdlx());

     map.put("page3_yqcglx", kcjbxxEntity.getYqcglx());

     map.put("page3_dwmc", kcjbxxEntity.getDwmc());

     map.put("page3_dwxz", kcjbxxEntity.getDwxz());

     map.put("page3_txdz", kcjbxxEntity.getTxdz());

     map.put("page3_yzbm", kcjbxxEntity.getYzbm());

     map.put("page3_szdq", kcjbxxEntity.getSzdq());

     map.put("page3_dwzgbm", kcjbxxEntity.getDwzgbm());

     map.put("page3_lxdh", kcjbxxEntity.getLxdh());

     map.put("page3_zzjgdm", kcjbxxEntity.getZzjgdm());

     map.put("page3_czhm", kcjbxxEntity.getCzhm());

     map.put("page3_dwclsj", kcjbxxEntity.getDwclsj());

     map.put("page3_dzxx", kcjbxxEntity.getDzxx());

   }

 

   /**

    * 储存课题封面数据

    *

    * @param uid 用户编号

    * @param map 储存数据的map集合

    */

   private void createKtfm(Integer uid, Map<String, Object> map) {

     // 根据用户编号查询封面数据

     KtfmEntity ktfmEntity = ktfmService.selectKtfmByUid(uid);

     // 添加到map集合

     map.put( "page1_zxmc" , "5G总体及关键器件" );

     map.put( "page1_xmbh" , "2016ZX03001_001" );

     map.put( "page1_xmmc" , "新一代宽带无线移动通信网" );

     map.put( "page1_ktbh" , "2016ZX03001_001_002" );

     map.put( "page1_ktmc" , "5G高性能基站A/D、D/A转换器试验样片研发" );

     map.put( "page1_zrdw" , "program_test" );

     map.put( "page1_ktzz" , ktfmEntity.getKtfzr());

     map.put( "page1_ktnx1" , "2016-01-01" );

     map.put( "page1_ktnx2" , "2017-12-31" );

     map.put( "page1_tbrq" , "2020-12-28" );

     map.put( "page1_nian" , "二一" );

     map.put( "page1_yue" , "一" );

   }

 

}

以上就是Java 实现word模板转为pdf的详细内容,更多关于Java word模板转为pdf的资料请关注其它相关文章!

原文链接:https://HdhCmsTestcnblogs测试数据/yoojyn/p/14386157.html

查看更多关于Java 实现word模板转为pdf的详细内容...

  阅读:18次