“This is the first day of my participation in the August More Text Challenge.

Recently, in the development, I have the requirement to export Word according to the template, and attach echarts legend to Word. I started to use Freework to get FTL template, but due to the trouble of conversion, I need to define the format OF XML and then convert it into FTL file, so I changed to use POI to directly assign value from Word template. And by splicing tags to achieve the image attached and define the width height.

1. Controller code

package com.springboot.util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVerticalJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import net.sf.json.JSONObject;


@Controller
public class WordTest {

    @RequestMapping("/exportSellPlan")
    public @ResponseBody void exportSellPlan(Long id, HttpServletRequest request, HttpServletResponse response)throws Exception{
         String rpName=request.getParameter("rpName")==null?"":request.getParameter("rpName");
            rpName=java.net.URLDecoder.decode(rpName,"UTF-8")  ;
            String title = rpName;
            OutputStream out = null;
            String path="C:\Users\Administrator\Desktop\demo.docx";
            //String path = request.getSession().getServletContext().getRealPath("/efficiency/EnergyCellReport/中能瑞通模板.docx"); 
            try {
                out = response.getOutputStream();
                
                /**
                 * 读取word
                 */
                XWPFDocument docx = PropertiesUtil.importWord(path);
                //docx = mFaultReportManageService.fillWordDataByList(docx, maps);
                /**
                 * 数据组装
                 */
                //获取所有需要填充的数据
                //List<Map<String,String>> codeList = energyUnitService.queryEnergyReportDiList(rpId, consId);
                
                Map<String, String> wdmap = new HashMap<String, String>();
                com.alibaba.fastjson.JSONObject json=new com.alibaba.fastjson.JSONObject();
//                String appId=UserUtil.getAppId();
//                json.put("appId", appId);        
//                TenantAppClone app=energyUnitService.selectObjectByID(json);
                wdmap.put("Title-N01","aaa");
                Map<String,Object> map = new HashMap<>();
                map.put("filepath", "C:\Users\Administrator\Desktop\50a6dcc7ly1g2g62aqxzpj22re1ulx6p.jpg");
                map.put("width", "100");
                map.put("height", "100");
                wdmap.put("img-scoreimg",String.valueOf(JSONObject.fromObject(map)));
                replaceInPara(docx,wdmap);
                /*boolean flag_cp=false;
                if(codeList!=null&&codeList.size()>0){
                    for(Map<String,String> map:codeList){
                         if(map.get("CODE_VALUE").equals("the-cpname")){
                             flag_cp=true;
                         }
                         
                    }
                }
                //填充word中的产品表格
                if(flag_cp){
                    this.queryProduct(docx,rpTime);
                }
                //填充值 
                //this.writeInWord(codeList,docx,rpTime);
                Map<String, String> wdmap = new HashMap<String, String>();
                if(codeList!=null&&codeList.size()>0){
                    for(int i=0;i<codeList.size();i++){
                        Map map = codeList.get(i);
                        wdmap.put(map.get("CODE_VALUE").toString(),map.get("RP_VALUE").toString());  //公司名称
                    }
                }
                //修改word中的值
                replaceInPara(docx,wdmap);*/
                /**
                 * 生成word
                 */
                PropertiesUtil.exportWord(docx, title, out, request, response);
                
                
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (out != null) {
                        out.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    }
    
    
    /**
     *  word中 的文字填入
     * @param docx
     * @param params
     */
    public void replaceInPara(XWPFDocument docx, Map<String, String> params) {
        Iterator<XWPFParagraph> itPara = docx.getParagraphsIterator();
        while (itPara.hasNext()) {
            XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
            Set<String> set = params.keySet();
            Iterator<String> iterator = set.iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                List<XWPFRun> run = paragraph.getRuns();
                for (int i = 0; i < run.size(); i++) {
                    System.out.println(run.get(i).getText(run.get(i).getTextPosition())+"-------------------------");
                    if (run.get(i).getText(run.get(i).getTextPosition()) != null&& run.get(i).getText(run.get(i).getTextPosition()).equalsIgnoreCase(key)) {
                        if (!(key.startsWith("img-"))) { 
                            run.get(i).setText(params.get(key), 0);
                        } else {

                            run.get(i).setText("", 0);
                            
                            Map<String, String> pic = new HashMap<String, String>();
                            System.err.println(params.get(key));
                            JSONObject jsonObject = JSONObject.fromObject(params.get(key));
                            for (Iterator<?> iter = jsonObject.keys(); iter.hasNext();)
                            {
                                String k = (String) iter.next();
                                String v = jsonObject.get(k).toString();
                                pic.put(k, v);
                            }
                            
                            int width = Integer.parseInt(pic.get("width").toString()); 
                            int height = Integer.parseInt(pic.get("height").toString()); 

                            byte[] byteArray = null;  
                            FileInputStream in = null;
                            try {  
                                in = new FileInputStream(pic.get("filepath").toString());
                                int total = in.available();  
                                byteArray = new byte[total];  
                                in.read(byteArray);  
                            } catch (IOException e) {  
                                e.printStackTrace();
                            }finally{
                                try {
                                    in.close();
                                } catch (Exception e2) {
                                    System.out.println("关闭流失败");
                                }
                            }
                            
                            int picType = XWPFDocument.PICTURE_TYPE_PNG;  
                            ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);  
                            try {  
                                String ind = docx.addPictureData(byteInputStream,picType);  
                                //docx.createPicture(width , height,paragraph);
                                
                                final int EMU = 9525;    
                                width *= EMU;    
                                height *= EMU;    
                                String blipId = ind;    
                                CTInline inline = paragraph.createRun().getCTR().addNewDrawing().addNewInline();    
                                String picXml = ""    
                                        + "<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">"    
                                        + "   <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">"    
                                        + "      <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">"    
                                        + "         <pic:nvPicPr>" + "            <pic:cNvPr id=""    
                                        + 1    
                                        + "" name="Generated"/>"    
                                        + "            <pic:cNvPicPr/>"    
                                        + "         </pic:nvPicPr>"    
                                        + "         <pic:blipFill>"    
                                        + "            <a:blip r:embed=""    
                                        + blipId    
                                        + "" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"/>"    
                                        + "            <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(1);      
                                docPr.setName("图片" + 1);      
                                docPr.setDescr("测试");
                                    
                                    
                                
                            } catch (Exception e) {  
                                e.printStackTrace();  
                            }  
                            
                        }
                    }
                    
                }
            }
        }

    }
}
Copy the code

2. PropertiesUtil:

package com.springboot.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.apache.poi.xwpf.usermodel.XWPFTableCell; import org.apache.poi.xwpf.usermodel.XWPFTableRow; Public class PropertiesUtil {/** * export word * @param docx * @param title * @param out *  @param request * @param response * @throws Exception */ public static void exportWord(XWPFDocument docx, String title, OutputStream out, HttpServletRequest request, HttpServletResponse Response) throws Exception {// Compatible browser String userAgent = request.getHeader(" user-agent "); if (! Stringutils. contains(userAgent, "Mozilla")) {// Mozilla firefox title = URLEncoder. Encode (title, "utF-8 "); Else {title = new String(title. GetBytes (" utF-8 "), "ISO8859-1"); } response.setContentType("application/msword"); response.addHeader("Accept-Ranges", "bytes"); response.addHeader("Content-Disposition", "attachment; filename=" + title + ".doc"); // Create word document try {docx.write(out); } catch (IOException e) { e.printStackTrace(); } finally { out.close(); }} /** * read word * @param fileName * @return * @throws Exception */ public static XWPFDocument importWord(String) fileName) throws Exception { InputStream in = null; XWPFDocument docx = null; try { in = new FileInputStream(new File(fileName)); docx = new XWPFDocument(in); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { in.close(); } return docx; } public static int getNullValuePos(XWPFTable table) {List<XWPFTableRow> rows =  null; List<XWPFTableCell> cells = null; XWPFTableRow row = null; rows = table.getRows(); Int t = -1; int t = -1; for (int i = 0; i < rows.size(); Row = rows.get(I); // Get all cells of the current row = row.gettablecells (); Int cellSize = cells.size(); XWPFTableCell cell = cells.get(cellsize-1); String text = cell.getText().trim(); if (StringUtils.isBlank(text)) { t = i; break; } } return t; }}Copy the code

3, Excel template: (according to the code I only example an assignment parameter of a picture parameter)

Filling it:

Fill the image:

Example code assignment :(image needs three parameters address, width, height)

Effect of 3,

The value effect:

Image effect: