天天看點

利用Freemarker模闆生成doc或者docx文檔(轉載整理)

可以直接看主要代碼實作

doc作為模闆檔案生成指定格式的doc檔案

實作邏輯

1、把作為模闆的doc檔案另存為xml檔案

利用Freemarker模闆生成doc或者docx文檔(轉載整理)

2、凡是需要填充的資料用${xxxx}替代

3、利用Template類将資料填充到模闆并生成檔案

代碼:

/**
 * 将資料以特定模闆格式輸出到word文檔(目前僅支援輸出doc檔案,隻能通過代碼修改文字内容)
 * @param data 輸入模闆資料
 * @param templatePath 模闆存放路徑
 * @param templateName 模闆名稱(XXX.xml,由doc/docx文檔轉換而成)
 * @param exFilePath 輸出檔案路徑
 * @param exFileName 輸出檔案名稱(XXX.doc)
 * @return
 */
public static boolean createDoc(Map<String,Object> data,String templatePath,String templateName,String exFilePath,String exFileName) {
	boolean result = false;
	Writer out = null;
	URL basePath = WordUtils.class.getClassLoader().getResource("");//擷取類檔案所在根目錄,注意是編譯後的class檔案目錄
    try {
    	Configuration configuration = new Configuration();
    	configuration.setDefaultEncoding("UTF-8");
    	configuration.setDirectoryForTemplateLoading(new File(basePath.getPath() + templatePath));
    	Template t = configuration.getTemplate(templateName); //擷取模闆檔案
        File file = new File(basePath.getPath() + exFilePath);//生成生成檔案所在目錄
        if (!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
    	File outFile = new File(basePath.getPath() + exFilePath + separator + exFileName); //導出檔案生成
    	out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
    	t.process(data, out); //将填充資料填入模闆檔案并輸出到目标檔案 
    	result = true;
	} catch (Exception e) {
		e.printStackTrace();
	} finally{
		try {
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	return result;
}
           

docx作為模闆檔案生成自定義格式的doc/docx檔案

實作邏輯

1、把doc/docx文檔修改為ZIP格式(直接修改字尾)

2、取出

word/document.xml(主要内容)

[Content_Types].xml、\word_rels\document.xml.rels(圖檔配置)

word/header1.xml(頁眉)

……

3、根據需要替換的内容修改以上檔案,具體見替換檔案說明

4、以zip檔案的形式處理模闆檔案(doc/docx) ,周遊該zip,将zip内除了media目錄下的檔案(圖檔另外處理)和替換檔案(步驟3内檔案)的每個檔案輸出到指定檔案(doc/docx,以zip流的形式輸入)

String xmlDocumentXmlRelsComment = FreeMarkUtils.getFreemarkerContent(dataMap, xmlDocumentXmlRels, templatePath);
ByteArrayInputStream documentXmlRelsInput = new ByteArrayInputStream(xmlDocumentXmlRelsComment.getBytes());//替換的xml

ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream("D:/workplace/springBootWorkplace/myDemo/target/classes/templates/out.docx"));
ZipFile zipFile = new ZipFile("D:/workplace/springBootWorkplace/myDemo/target/classes/templates/docTemplates.docx");//以zip檔案的形式處理docx檔案
Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();//周遊zip檔案内的所有檔案
int len = -1;
byte[] buffer = new byte[1024];
while (zipEntrys.hasMoreElements()) {
ZipEntry next = zipEntrys.nextElement();//以枚舉方式擷取檔案
InputStream is = zipFile.getInputStream(next);//用于檔案輸出
zipout.putNextEntry(new ZipEntry(next.getName()));//開始寫入,設定檔案名稱
  if (documentXmlRelsInput != null) {
      while ((len = documentXmlRelsInput.read(buffer)) != -1) {
         zipout.write(buffer, 0, len);
documentXmlRelsInput.close();
}else{
  while ((len = is.read(buffer)) != -1) {
  	zipout.write(buffer, 0, len);
  }
}
is.close();
}
zipout.close();
zipFile.close();
           

5、将替換檔案和圖檔檔案(word/media)以zip流形式輸入到指定檔案

6、關閉流

word轉換zip後替換檔案說明

1、\word\document.xml

用來存在word文檔的主要資料資訊

2、\word_rels\document.xml.rels

用來存在word文檔的主要資料配置 包括圖檔的指向

<Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.jpeg"/>
rId7:唯一辨別,image1.jpeg:圖檔名稱
           

與對應的document.xml

<wp:docPr id="2" name="圖檔 2" descr="D:\阿裡工作\裝修\裝修\北歐1\1.jpg"/>
           

id:唯一辨別,name:辨別,descr:圖檔路徑

<a:blip r:embed="rId7">
           

r:embed對應document.xml.rels的Id

<w:p w:rsidR="00EC2516" w:rsidRPr="00EC2516" w:rsidRDefault="00EC2516" w:rsidP="00EC2516">
  <w:r w:rsidRPr="00EC2516">
    <w:rPr>
      <w:noProof/>
    </w:rPr>
    <w:drawing>
      <wp:inline distT="0" distB="0" distL="0" distR="0">
        <wp:extent cx="5274310" cy="7024797"/>
        <wp:effectExtent l="0" t="0" r="2540" b="5080"/>
        <wp:docPr id="2" name="圖檔 2" descr="D:\阿裡工作\裝修\裝修\北歐1\1.jpg"/>
        <wp:cNvGraphicFramePr>
          <a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"></a:graphicFrameLocks>
        </wp:cNvGraphicFramePr>
        <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="0" name="Picture 2" descr="D:\阿裡工作\裝修\裝修\北歐1\1.jpg"/>
                <pic:cNvPicPr>
                  <a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
                </pic:cNvPicPr>
              </pic:nvPicPr>
              <pic:blipFill>
                <a:blip r:embed="rId7">
                  <a:extLst>
                    <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
                      <a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"></a14:useLocalDpi>
                    </a:ext>
                  </a:extLst>
                </a:blip>
                <a:srcRect/>
                <a:stretch>
                  <a:fillRect/>
                </a:stretch>
              </pic:blipFill>
              <pic:spPr bwMode="auto">
                <a:xfrm>
                  <a:off x="0" y="0"/>
                  <a:ext cx="5274310" cy="7024797"/>
                </a:xfrm>
                <a:prstGeom prst="rect">
                  <a:avLst/>
                </a:prstGeom>
                <a:noFill/>
                <a:ln>
                  <a:noFill/>
                </a:ln>
              </pic:spPr>
            </pic:pic>
          </a:graphicData>
        </a:graphic>
      </wp:inline>
    </w:drawing>
  </w:r>
</w:p>
           

3、\word\header1.xml

用來配置docx文檔的頁眉檔案

頁眉:Word文檔模闆測試ymdhis

<w:p w:rsidR="00DF53B8" w:rsidRDefault="00DF53B8" w:rsidP="00DF53B8">
    <w:pPr>
      <w:pStyle w:val="a3"/>
    </w:pPr>
    <w:r>
      <w:t>Word</w:t>
    </w:r>
    <w:r>
      <w:t>文檔模闆測試</w:t>
    </w:r>
    <w:r w:rsidR="00CC7E39">
      <w:t>ymdhis</w:t>
    </w:r>
  </w:p>
           

4、[Content_Types].xml

用來配置 docx文檔中所插入圖檔的類型 如 png、jpeg、jpg等

,XX的格式要與插入檔案的格式一緻,每種類别加一條記錄

<Default Extension="jpeg" ContentType="image/jpeg"/>
           

代碼

pom.xml

<dependency>  
    <groupId>org.freemarker</groupId>  
    <artifactId>freemarker</artifactId>  
    <version>2.3.23</version>  
</dependency>  
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.1.0</version>
   <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.1</version>
</dependency>
           
/**
 * 擷取目前日期的字元串(毫秒) 如
 * @return
 */
public static String getCurrentTime_yyyyMMddHHmmssSSS(){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    return sdf.format(new Date());
}
           
/**
     * 将模闆填充完資料以字元串形式輸出
     * @param dataMap   參數
     * @param templateName  模闆名稱
     * @param temp_path  模闆路徑 classes下的路徑 如果  classes/templates  傳入 /templates即可
     * @return
     */
    public static String getFreemarkerContent(Map dataMap, String templateName, String temp_path) {
        String result = "";
        try {
            //建立配置執行個體
            Configuration configuration = new Configuration();

            //設定編碼
            configuration.setDefaultEncoding("UTF-8");

            //ftl模闆檔案統一放至 com.lun.template 包下面
//            configuration.setDirectoryForTemplateLoading(new File("D:/idea_workspace/alarm/alarm/src/main/resources/template/"));
            configuration.setClassForTemplateLoading(FreeMarkUtils.class, temp_path);
            //擷取模闆
            Template template = configuration.getTemplate(templateName);

            StringWriter swriter = new StringWriter();
            //将填充資料填入模闆檔案并輸出到目标檔案/流
            template.process(dataMap, swriter);
            result = swriter.toString();


        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
           
/**
     * 将模闆填充完資料以流形式輸出
     * @param dataMap   參數
     * @param templateName  模闆名稱
     * @param tempPath  模闆路徑 classes下的路徑 如果  classes/templates  傳入 /templates即可
     * @return
     */
    public static ByteArrayInputStream getFreemarkerContentInputStream(Map dataMap, String templateName, String tempPath) {
        ByteArrayInputStream in = null;

        try {
            //建立配置執行個體
            Configuration configuration = new Configuration();

            //設定編碼
            configuration.setDefaultEncoding("UTF-8");

            //ftl模闆檔案統一放至 com.lun.template 包下面
//            configuration.setDirectoryForTemplateLoading(new File("D:/idea_workspace/alarm/alarm/src/main/resources/template/"));
            configuration.setClassForTemplateLoading(FreeMarkUtils.class, tempPath);
            //擷取模闆
            Template template = configuration.getTemplate(templateName);

            StringWriter swriter = new StringWriter();
            //生成檔案
            template.process(dataMap, swriter);
            //String result = swriter.toString();
            in = new ByteArrayInputStream(swriter.toString().getBytes());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return in;
    }
           

**

主要代碼實作

**

import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    import java.io.*;
    import java.net.URL;
    import java.util.*;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;
    import java.util.zip.ZipOutputStream;
    
    /**
     * 注意該方法所在工程是springboot結構,模闆放置于\src\main\resources\templates\下,其他工程結構要将讀取路徑對應修改
     * frameMark:${title}
     * @author Administrator
     *
     */
    public class WordUtils {
    
        private final static String separator = File.separator;
        private final static String suffix_docx = "docx";
        private final static String suffix_doc = "doc";
    
    	/**
    	 * 将資料以特定模闆格式輸出到word文檔(目前僅支援輸出doc檔案,隻能通過代碼修改文字内容)
    	 * @param data 輸入模闆資料
    	 * @param templatePath 模闆存放路徑
    	 * @param templateName 模闆名稱(XXX.xml,由doc/docx文檔轉換而成)
    	 * @param exFilePath 輸出檔案路徑
    	 * @param exFileName 輸出檔案名稱(XXX.doc)
    	 * @return
    	 */
    	public static boolean createDoc(Map<String,Object> data,String templatePath,String templateName,String exFilePath,String exFileName) {
    		boolean result = false;
    		Writer out = null;
    		URL basePath = WordUtils.class.getClassLoader().getResource("");//擷取類檔案所在根目錄,注意是編譯後的class檔案目錄
            try {
            	Configuration configuration = new Configuration();
            	configuration.setDefaultEncoding("UTF-8");
            	configuration.setDirectoryForTemplateLoading(new File(basePath.getPath() + templatePath));
            	Template t = configuration.getTemplate(templateName); //擷取模闆檔案
                File file = new File(basePath.getPath() + exFilePath);//生成生成檔案所在目錄
                if (!file.exists() && !file.isDirectory()) {
                    file.mkdirs();
                }
            	File outFile = new File(basePath.getPath() + exFilePath + separator + exFileName); //導出檔案生成
            	out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
            	t.process(data, out); //将填充資料填入模闆檔案并輸出到目标檔案 
            	result = true;
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally{
    			try {
    				out.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    		
    		return result;
    	}
        
        /**
         * 以docx為模闆生成doc/docx檔案
         * 模闆檔案的配置檔案由docx轉換成zip擷取,docx文檔生成工具類  (改變字尾名即可)
         * 在使用制作模闆的過程中如果模闆中有圖檔那就保留圖檔,修改[Content_Types].xml和document.xml.rels文檔,如果模闆中沒有圖檔 則不需要設定[Content_Types].xml和document.xml.rels
         * 由于word模闆的個性化 是以 每次做模闆都要重新覆寫原來的模闆
         * @param dataMap				參數資料
         * @param docxTemplateFile		docx模主機闆名稱(注意模闆檔案隻能為docx,doc不能被作為zip讀取)
         * @param xmlDocument			docx中document.xml模闆檔案  用來存放word文檔的主要資料資訊
         * @param xmlDocumentXmlRels	docx中document.xml.rels 模闆檔案  用來存放word文檔的主要資料配置 包括圖檔的指向
         * @param xmlContentTypes		docx中 [Content_Types].xml 模闆檔案 用來配置 docx文檔中所插入圖檔的類型 如 png、jpeg、jpg等
         * @param xmlHeader				docx中 header1.xml 模闆檔案 用來配置docx文檔的頁眉檔案
         * @param templatePath			模闆存放路徑 如 /templates/
         * @param outputFileTempPath	所生成的docx檔案的臨時路徑檔案夾 如果 temp/20180914051811/
         * @param outputFileName		所生成的docx檔案名稱  如  xxx.docx  或  xxx.doc
         * @throws Exception
         */
        public static void createDocx(Map<String, Object> dataMap, String docxTemplateFile, String xmlDocument, String xmlDocumentXmlRels,
                                      String xmlContentTypes, String xmlHeader, String templatePath,
                                      String outputFileTempPath, String outputFileName) throws Exception {
    
            URL basePath = WordUtils.class.getClassLoader().getResource("");//擷取類檔案所在根目錄,注意是編譯後的class檔案目錄
            String realTemplatePath = basePath.getPath() + templatePath;
            //臨時檔案産出的路徑
            String outputPath = basePath.getPath() + outputFileTempPath;
            try {
    
    
                //================================擷取 document.xml.rels 輸入流================================
                String xmlDocumentXmlRelsComment = FreeMarkUtils.getFreemarkerContent(dataMap, xmlDocumentXmlRels, templatePath);
                ByteArrayInputStream documentXmlRelsInput = new ByteArrayInputStream(xmlDocumentXmlRelsComment.getBytes());
    
                //================================擷取 header1.xml 輸入流================================
                ByteArrayInputStream headerInput = FreeMarkUtils.getFreemarkerContentInputStream(dataMap, xmlHeader, templatePath);
    
                //================================擷取 [Content_Types].xml 輸入流================================
                ByteArrayInputStream contentTypesInput = FreeMarkUtils.getFreemarkerContentInputStream(dataMap, xmlContentTypes, templatePath);
    
    
                //讀取 document.xml.rels  檔案 并擷取rId 與 圖檔的關系 (如果沒有圖檔 此檔案不用編輯直接讀取就行了)
                Document document = DocumentHelper.parseText(xmlDocumentXmlRelsComment);
                Element rootElt = document.getRootElement(); // 擷取根節點
                Iterator iter = rootElt.elementIterator();// 擷取根節點下的子節點head
                List<Map<String, String>> picList = (List<Map<String, String>>) dataMap.get("picList");
    
                // 周遊Relationships節點,擷取Target類型為media的節點(該節點由frameMark生成),将其Id值映射到picList的子項,對應rId
                while (iter.hasNext()) {
                    Element recordEle = (Element) iter.next();
                    String id = recordEle.attribute("Id").getData().toString();
                    String target = recordEle.attribute("Target").getData().toString();
                    if (target.indexOf("media") == 0) {
                        for (Map<String, String> picMap : picList) {
                            if (target.endsWith(picMap.get("name"))) {
                                picMap.put("rId", id);
                            }
                        }
                    }
                }
                dataMap.put("picList", picList);//覆寫原來的picList,主要為了關聯 document.xml.rels内的圖檔配置聲明;
    
                //================================擷取 document.xml 輸入流================================
                ByteArrayInputStream documentInput = FreeMarkUtils.getFreemarkerContentInputStream(dataMap, xmlDocument, templatePath);
    
    
                File docxFile = new File(realTemplatePath + separator + docxTemplateFile);
                if (!docxFile.exists()) {
                    docxFile.createNewFile();
                }
    
                ZipFile zipFile = new ZipFile(docxFile);//模闆檔案隻能為docx類型,doc類型不能被作為zip讀取
                Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();//用于周遊壓縮檔案内的每個檔案
                File tempPath = new File(outputPath);
                //如果輸出目标檔案夾不存在,則建立
                if (!tempPath.exists()) {
                    tempPath.mkdirs();
                }
                ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(outputPath + outputFileName));
    
    
                //================================覆寫文檔-begin================================
                //邏輯說明:将模闆檔案(doc/docx)以zip形式處理,周遊該zip,将zip内除了media目錄下的檔案(圖檔另外處理)的每個檔案輸入到指定檔案(doc/docx,以zip形式輸入),其中[Content_Types].xml、document.xml.rels、word/document.xml、word/header1.xml用frameMark生成的檔案替代
                int len = -1;
                byte[] buffer = new byte[1024];
                while (zipEntrys.hasMoreElements()) {
                    ZipEntry next = zipEntrys.nextElement();//以枚舉方式擷取檔案
                    InputStream is = zipFile.getInputStream(next);
                    if (next.toString().indexOf("media") < 0) {
                        // 把輸入流的檔案傳到輸出流中 如果是word/document.xml由我們輸入
                        zipout.putNextEntry(new ZipEntry(next.getName()));//開始寫入,設定檔案名稱
    //                    System.out.println("next.getName()>>>" + next.getName() + "  next.isDirectory()>>>" + next.isDirectory());
                        //寫入圖檔配置類型
                        if (next.getName().equals("[Content_Types].xml")) {
                            if (contentTypesInput != null) {
                                while ((len = contentTypesInput.read(buffer)) != -1) {
                                    zipout.write(buffer, 0, len);
                                }
                                contentTypesInput.close();
                            }
    
                        } else if (next.getName().indexOf("document.xml.rels") > 0) {
                            //寫入填充資料後的主資料配置資訊
                            if (documentXmlRelsInput != null) {
                                while ((len = documentXmlRelsInput.read(buffer)) != -1) {
                                    zipout.write(buffer, 0, len);
                                }
                                documentXmlRelsInput.close();
                            }
                        } else if ("word/document.xml".equals(next.getName())) {
                            //寫入填充資料後的主資料資訊
                            if (documentInput != null) {
                                while ((len = documentInput.read(buffer)) != -1) {
                                    zipout.write(buffer, 0, len);
                                }
                                documentInput.close();
                            }
    
                        } else if ("word/header1.xml".equals(next.getName())) {
                            //寫入填充資料後的頁眉資訊
                            if (headerInput != null) {
                                while ((len = headerInput.read(buffer)) != -1) {
                                    zipout.write(buffer, 0, len);
                                }
                                headerInput.close();
                            }
    
                        } else {//其餘檔案直接輸出到導出檔案
                            while ((len = is.read(buffer)) != -1) {
                                zipout.write(buffer, 0, len);
                            }
                            is.close();
                        }
    
                    }
    
                }
    
                //------------------寫入新圖檔-start------------------
                len = -1;
                if (picList != null && !picList.isEmpty()) {
                    for (Map<String, String> pic : picList) {
                        ZipEntry next = new ZipEntry("word" + separator + "media" + separator + pic.get("name"));
                        zipout.putNextEntry(new ZipEntry(next.toString()));
                        InputStream in = new FileInputStream(pic.get("path"));
                        while ((len = in.read(buffer)) != -1) {
                            zipout.write(buffer, 0, len);
                        }
                        in.close();
                    }
                }
    
    
                //------------------寫入新圖檔-over------------------
                //================================覆寫文檔-end================================
                zipout.close();
                zipFile.close();
            } catch (Exception e) {
                e.printStackTrace();
                throw new Exception("生成word檔案失敗!");
            }
    
        }
    
        public static void main(String[] args) {
    
        	//============================================createDocx(docx模闆測試)-begin============================================
        	String timeStr1 = DateUtils.getCurrentTime_yyyyMMddHHmmssSSS();
            String templatePath1 = separator + "templates" + separator;
            String outputFileTempPath1 = "temp" + separator + "doc" + separator + timeStr1 + separator;
            String outputFileName1 = timeStr1 + "."+suffix_doc;
        	
    		Map<String,Object> dataMap1 = new HashMap<String,Object>();
            dataMap1.put("name", "王大壯"); 
            dataMap1.put("age", "30"); 
            dataMap1.put("phone", "18450098635"); 
            dataMap1.put("mailbox", "12345678911");
            System.out.println(createDoc(dataMap1, templatePath1, "docTemplates.xml", outputFileTempPath1,outputFileName1));
          //============================================createDocx(docx模闆測試)-end============================================
        	
        	//============================================createDocx(docx模闆測試)-begin============================================
            URL basePath = WordUtils.class.getClassLoader().getResource("");
            String picPath = basePath.getPath() + separator + "templates" + separator;
            ;
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("ymdhis", DateUtils.getCurrentTime_yyyyMMddHHmmss());
            List<String> listTile = new ArrayList<>();
            listTile.add("這是第一個标題");
            listTile.add("這是第二個标題");
            listTile.add("這是第三個标題");
            dataMap.put("listTitle", listTile);
    
            List<String> picTypes = new ArrayList<>();
            picTypes.add("jpg");
            dataMap.put("picTypes", picTypes);
    
            List<Map<String, String>> picList = new ArrayList<>();
    
            Map<String, String> picMap = new HashMap<>();
            // 要按順序
            picMap.put("path", picPath + "pic1.jpg");
            picMap.put("name", "pic1.jpg");
            picList.add(picMap);
    
            picMap = new HashMap<>();
            picMap.put("path", picPath + "pic2.jpg");
            picMap.put("name", "pic2.jpg");
            picList.add(picMap);
    
            picMap = new HashMap<>();
            picMap.put("path", picPath + "pic3.jpg");
            picMap.put("name", "pic3.jpg");
            picList.add(picMap);
            dataMap.put("picList", picList);
            List<Map<String, Object>> listTaleData = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            map.put("name", "小明");
            map.put("age", "11");
            map.put("sex", "男");
            map.put("grade", "五年級");
            listTaleData.add(map);
    
            map = new HashMap<>();
            map.put("name", "小紅");
            map.put("age", "12");
            map.put("sex", "女");
            map.put("grade", "六年級");
            listTaleData.add(map);
    
            map = new HashMap<>();
            map.put("name", "小花");
            map.put("age", "13");
            map.put("sex", "女");
            map.put("grade", "七年級");
            listTaleData.add(map);
            dataMap.put("listTaleData", listTaleData);
    
            dataMap.put("summary", "總結總結總結!");
            
    
            String timeStr = DateUtils.getCurrentTime_yyyyMMddHHmmssSSS();
            String docxTemplateFile = "docxTemplates.docx";
            String xmlDocument = "document.xml";
            String xmlDocumentXmlRels = "document.xml.rels";
            String xmlContentTypes = "[Content_Types].xml";
            String xmlHeader = "header1.xml";//可以用來修改頁眉的一些資訊
            String templatePath = separator + "templates" + separator;
            String outputFileTempPath = "temp" + separator + "docx" + separator + timeStr + separator;
            String outputFileName = timeStr + "."+suffix_docx;
            String outputFileName2 = timeStr + "."+suffix_doc;
    
            try {
                createDocx(dataMap, docxTemplateFile, xmlDocument, xmlDocumentXmlRels, xmlContentTypes,
                        xmlHeader, templatePath, outputFileTempPath, outputFileName);
                createDocx(dataMap, docxTemplateFile, xmlDocument, xmlDocumentXmlRels, xmlContentTypes,
                        xmlHeader, templatePath, outputFileTempPath, outputFileName2);
            } catch (Exception e) {
                e.printStackTrace();
            }
          //============================================createDocx(docx模闆測試)-end============================================
        }
    
    
    }
           

模闆所在目錄

利用Freemarker模闆生成doc或者docx文檔(轉載整理)

模闆檔案

連結: https://pan.baidu.com/s/1ocavyv7wfB_bvptO3Ten3w 提取碼: fgwp

參考:https://blog.csdn.net/fenfenguai/article/details/78731331