您的位置 首页 java

POI动态插入数据到Word文档

模板制作

制作word模版,${xxxx}是要替换的内容。注意${xxxx}是一个整体,中间不能断开,因为利用 poi 的API程序操作时,判断是否有这个${xxxx}才进行替换。

依赖的包

<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi</artifactId>
 <version>3.15</version>
</dependency>
<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi-ooxml</artifactId>
 <version>3.15</version>
</dependency>
 

操作 docx 文件

POI在读写word docx文件时是通过xwpf模块来进行的,其核心是XWPFDocument。一个XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档。XWPFDocument中主要包含下面这几种对象:

  • XWPFParagraph:代表一个段落。
  • XWPFRun:代表具有相同属性的一段文本。
  • XWPFTable:代表一个表格。
  • XWPFTableRow:表格的一行。
  • XWPFTableCell:表格对应的一个单元格

具体代码:

/** 
 * 根据指定的参数值、模板,生成 word 文档 
 * @param param 需要替换的变量,key值与模板里${xxxx}的xxx一样 
 * @param template 模板,docx文档 
 */ 
 public CustomXWPFDocument generateWord(Map<String, Object> param, String template) {
 CustomXWPFDocument doc = null; 
 try { 
 OPCPackage pack = POIXMLDocument.openPackage(template); 
 doc = new CustomXWPFDocument(pack); 
 if (param != null && param.size() > 0) {
 //处理段落 
 List<XWPFParagraph> paragraphList = doc.getParagraphs(); 
 processParagraphs(paragraphList, param, doc); 
 
 //处理表格 
  Iterator <XWPFTable> it = doc.getTablesIterator(); 
 while (it.hasNext()) { 
 XWPFTable table = it.next(); 
 List<XWPFTableRow> rows = table.getRows();
 for (XWPFTableRow row : rows) {
 List<XWPFTableCell> cells = row.getTableCells();
 for (XWPFTableCell cell : cells) { 
 List<XWPFParagraph> paragraphListTable = cell.getParagraphs(); 
 processParagraphs(paragraphListTable, param, doc); 
 } 
 } 
 } 
 } 
 } catch (Exception e) { 
 e.printStackTrace(); 
 } 
 return doc; 
 }
 

/** 
 * 处理段落 
 * @param paragraphList 
 */ 
 public void processParagraphs(List<XWPFParagraph> paragraphList,Map<String, Object> param,CustomXWPFDocument doc){
 if(paragraphList != null && paragraphList.size() > 0){ 
 for(XWPFParagraph paragraph : paragraphList){
 List<XWPFRun> runs = paragraph.getRuns(); 
 for (XWPFRun run : runs) { 
 String text = run.getText(0); 
 if(text != null){ 
 boolean isSetText = false; 
 for (Entry<String, Object> entry : param.entrySet()) { 
 String key = "${"+ entry.getKey() +"}";
 if(text.indexOf(key) != -1){
 isSetText = true; 
 Object value = entry.getValue(); 
 if (value instanceof String) {//文本替换 
 text = text.replace(key, value.toString()); 
 //System.out.println(text);
 } else if (value instanceof Double) {
 text = text.replace(key, value.toString());
 } else if (value instanceof Map) {//图片替换
 text = text.replace(key, ""); 
 Map pic = (Map)value; 
 int width = Integer.parseInt(pic.get("width").toString()); 
 int height = Integer.parseInt(pic.get("height").toString()); 
 int picType = getPictureType(pic.get("type").toString()); 
  byte [] byteArray = (byte[]) pic.get("content"); 
 ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray); 
 try { 
 String ind = doc.addPictureData(byteInputStream, picType);
 int id = doc.getNextPicNameNumber(picType);
 createPicture(id, ind, width , height, run);
 //System.out.println("图片替换");
 } catch (Exception e) { 
 e.printStackTrace(); 
 } 
 } 
 } 
 } 
 if(isSetText){ 
 run.setText(text,0); 
 } 
 } 
 } 
 } 
 } 
 }
 

/** 
 * 根据图片类型,取得对应的图片类型代码 
 * @param picType 
 * @return int 
 */ 
 private int getPictureType(String picType){
 int res = CustomXWPFDocument.PICTURE_TYPE_PICT; 
 if(picType != null){ 
 if(picType.equalsIgnoreCase("png")){ 
 res = CustomXWPFDocument.PICTURE_TYPE_PNG;
 }else if(picType.equalsIgnoreCase("dib")){ 
 res = CustomXWPFDocument.PICTURE_TYPE_DIB; 
 }else if(picType.equalsIgnoreCase("emf")){ 
 res = CustomXWPFDocument.PICTURE_TYPE_EMF; 
 }else if(picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")){ 
 res = CustomXWPFDocument.PICTURE_TYPE_JPEG; 
 }else if(picType.equalsIgnoreCase("wmf")){ 
 res = CustomXWPFDocument.PICTURE_TYPE_WMF; 
 } 
 } 
 return res;
 } 
/** 
 * @param id 
 * @param width 宽 
 * @param height 高 
 * @param run 段落
 */ 
 public void createPicture(int id, String blipId, int width, int height,XWPFRun run) {
 final int EMU = 9525; 
 width *= EMU; 
 height *= EMU; 
 
 CT inline  inline = run.getCTR().addNewDrawing().addNewInline(); 
 String picXml = "" 
 + "<a:graphic xmlns:a="">" 
 + " <a:graphicData uri="">" 
 + " <pic:pic xmlns:pic="">" 
 + " <pic:nvPicPr>" + " <pic:cNvPr id="" 
 + id 
 + "" name="Generated"/>" 
 + " <pic:cNvPicPr/>" 
 + " </pic:nvPicPr>" 
 + " <pic:blipFill>" 
 + " <a:blip r:embed="" 
 + blipId 
 + "" xmlns:r=""/>" 
 + " <a: stretch >" 
 + " <a:fillRect/>" 
 + " </a:stretch>" 
 + " </pic:blipFill>" 
 + " <pic:spPr>" 
 + " <a:xfrm>" 
 + " <a:off x="0" y="0"/>" 
 + " <a:ext cx="" 
 + width 
 + "" cy="" 
 + height 
 + ""/>" 
 + " </a:xfrm>" 
 + " <a:prstGeom prst="rect">" 
 + " <a:avLst/>" 
 + " </a:prstGeom>" 
 + " </pic:spPr>" 
 + " </pic:pic>" 
 + " </a:graphicData>" + "</a:graphic>"; 
 
 inline.addNewGraphic().addNewGraphicData(); 
 XmlToken xmlToken = null; 
 try { 
 xmlToken = XmlToken.Factory.parse(picXml); 
 } catch (XmlException xe) { 
 xe.printStackTrace(); 
 } 
 inline.set(xmlToken); 
 
 inline.setDistT(0); 
 inline.setDistB(0); 
 inline.setDistL(0); 
 inline.setDistR(0); 
 
 CTPositiveSize2D extent = inline.addNewExtent(); 
 extent.setCx(width); 
 extent.setCy(height); 
 
 CTNonVisualDrawingProps docPr = inline.addNewDocPr(); 
 docPr.setId(id); 
 docPr.setName("图片" + id); 
 docPr.setDescr("测试"); 
 }
 

输出docx文档

把返回的XWPFDocument写入到对应的流中。

FileOutputStream fopts = new FileOutputStream("E://andy.docx");
doc.write(fopts);
 

转pdf文档

相关包的依赖:

<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.poi.xwpf.converter.core</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.poi.xwpf.converter.pdf</artifactId>
<version>2.0.1</version>
</dependency>
 

把XWPFDocument转成PDF:

FileOutputStream fopts = new FileOutputStream(new FIle("E://andy.pdf"));
PdfOptions options = PdfOptions.create();
options.fontProvider(new IFontProvider() {
 @Override
 public Font getFont(String s, String s1, float v, int i, Color color) {
 try {
 BaseFont bfChinese = BaseFont.createFont(rootPath + "wordtemplate/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
 Font fontChinese = new Font(bfChinese, v, i, color);
 if (s != null) {
 fontChinese.setFamily(s);
 }
 return fontChinese;
 } catch (Exception e) {
 e.printStackTrace();
 return null;
 }
 }
});
PdfConverter.getInstance().convert(doc, fopts, options);
 

其中doc就是要转的XWPFDocument。simsun.ttf 是字体文件。

最后测试后模板的处理结果:

文章来源:智云一二三科技

文章标题:POI动态插入数据到Word文档

文章地址:https://www.zhihuclub.com/184542.shtml

关于作者: 智云科技

热门文章

网站地图