精华内容
下载资源
问答
  • 最新个人劳动合同格式企业劳动合同标准格式word排版格式.docx
  • 毕业论文模板毕业论文模板Word标准毕业论文模板Word标准格式毕业论文模板Word标准格式
  • java使用freemarker导出标准格式word文档,导出docx格式word文档

    之前使用freemarker导出word,可以在PC上打开。但是它不能在手机上打开,因为它是xml格式的。所以后来又修改了导出方式,导出标准格式的word.
    (具体步骤和引用文件不再赘述,可先参考之前文章)
    之前的导出方式:请戳====>java使用freemarker导出word

    一、文件结构

    首先我们来看一下标准格式的word有哪些东西组成。

    1. 和上文一样,创建一个word文档trip.docx。
    2. 把后缀名docx改为zip
      在这里插入图片描述 在这里插入图片描述
      3. 解压后,查看文件夹内容结构如下:
      在这里插入图片描述
      在这里插入图片描述
    3. 查看各个文档后我们会发现
      根目录下的**[Content_Types].xml中指定文件的配置,比如图片格式,主题文件,样式文件等等;
      word文件夹下的
      media文件夹存放文档中的图片;
      word文件夹下的_rels文件夹下的
      document.xml.rels中则指定了文档中用的图片id和图片名称;
      word文件夹下的
      document.xml则是文档内容,也是我们要写入的文档模板。
      word文件夹下的
      header1.xml则是指定页眉
      这里没有写页脚,如果有页脚,会有
      footer.xml**的文件生成。
      想用和需要修改的就是上面几个文件了。

    二、思路分析

    1. 使用document.xml修改成需要的word模板
    2. 修改header1.xml中的页眉
    3. 在**[Content_Types].xml**自动生成或提前写入图片格式
    4. media文件夹下输出图片
    5. document.xml.rels中动态生成图片,id与document.xml中保持一致,名字写入文件夹media的一致
    6. 指定一个模板文件,用于生成相同格式

    三、模板修改

    1. 在resource文件夹下创建templates文件夹,把**[Content_Types].xml**、document.xmlheader1.xml****document.xml.rels放入templates中。
      在这里插入图片描述
    2. 其中**[Content_Types].xml**中的图片格式我没有动态生成,预先写入了我会用到的两种,如下:
    <?xml version="1.0" encoding="utf-8"?>
    
    <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
     
      <Default Extension="png" ContentType="image/png"/>
      <Default Extension="jpeg" ContentType="image/jpeg"/>
    <!-- 其他配置省略-->
    </Types>
    
    1. header1.xml写入页眉:${title}
    <?xml version="1.0" encoding="utf-8"?>
    
    <w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 wp14">
      <w:p w:rsidR="006747D4" w:rsidRDefault="008E4089">
        <w:pPr>
          <w:pStyle w:val="a3"/>
        </w:pPr>
        <w:r>
          <w:t>${title}</w:t>
        </w:r>
      </w:p>
    </w:hdr>
    
    1. document.xml.rels生成图片
    <?xml version="1.0" encoding="utf-8"?>
    
    <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
      <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/>
      <Relationship Id="rId12" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>
      <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/>
      <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
      <Relationship Id="rId11" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/>
      <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" Target="endnotes.xml"/>
      <Relationship Id="rId10" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/>
      <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/>
    
      <!-- 注意id,需要和文件中对应,如果不对应,最终生成的文件会出错-->
      
      <Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.jpeg"/>
      <Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image2.jpeg"/>
      <Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image3.jpeg"/>
    
    <!-- 注意id的生成,避免重复。这里我自己在rId后又加了1作为前缀-->
    
       <#if dayDetail?? && (dayDetail?size > 0)>
    	    <#list dayDetail as detail>
    	        <#if detail.contents?? && (detail.contents?size > 0)>
    	            <#list detail.contents as detailContent>
    	                <#if (detailContent.url)?? && (detailContent.url) !="">
    	                    <Relationship Id="rId1${detail_index+1}${detailContent_index+1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image${detail_index+1}${detailContent_index+1}.png"/>
    	                </#if>
    	            </#list>
    	        </#if>
    	    </#list>
    	</#if>
    </Relationships>
    
    
    1. document.xml生成需要的文档模板,一般类型就用${title}这种替代。这里主要列出图片格式。
    <!-- 图片id-->
    <wp:docPr id="${detail_index+1}${detailContent_index+1}" name="图片 ${detail_index+1}${detailContent_index+1}"/>
    
    <!-- 图片名-->
     <pic:nvPicPr>
       <pic:cNvPr id="0" name="Picture ${detail_index+1}${detailContent_index+1}"/>
        <pic:cNvPicPr>
          <a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
        </pic:cNvPicPr>
      </pic:nvPicPr>
    
     <!-- 图片rId1-->
    <a:blip r:embed="rId1${detail_index+1}${detailContent_index+1}" cstate="print">
    

    代码编写

    private Configuration configuration = null;
    	
    	@Value("${filePath}")
    	private String filePath;
    	
    	@Value("${filePathAlias}")
    	private String filePathAlias;
    	
    	private final static String separator = File.separator;
        private final static String suffix_docx = "docx";
        
        private final static String docxTemplateFile = "docTemplates.docx";
        private final static String xmlDocument = "document.xml";
        private final static String xmlDocumentXmlRels = "document.xml.rels";
        private final static String xmlContentTypes = "[Content_Types].xml";
        private final static String xmlHeader = "header1.xml";//可以用来修改页眉的一些信息
    	
    	@PostConstruct
    	public void init(){
    		configuration = new Configuration(Configuration.VERSION_2_3_28);
    		configuration.setDefaultEncoding("UTF-8");
    		configuration.setClassForTemplateLoading(this.getClass(), "/templates/");
    	}
    
    	@Override
    	public String exportWord(TripExportDTO u) throws Exception {
    		String url = this.createDocx(u);
    		return url;
    	}
    
    @SuppressWarnings("resource")
    	private String createDocx(TripExportDTO u) throws Exception {
    		String timeStr = DateUtils.date2Str(new Date(), DateUtils.DEFAULT_DATETIME_PATTERN_TRIM);
            String templatePath = separator + "templates" + separator;
            String urlFileName = URLEncoder.encode(u.getTitle(), "UTF-8") + "-" + timeStr + "."+ suffix_docx;
            String outputFileName = u.getTitle() + "-" + timeStr + "."+ suffix_docx;
            
            //这里生成的文件路径和返回出去的文件路径不同,做了文件路径跳转
    		String outputFileTempPath = "temp" + separator + timeStr + "-" + u.getId() + separator;
    		String realTemplatePath = filePath + templatePath;
    		String outputPath = filePath + outputFileTempPath;
    		
    		//获取 document.xml.rels 输入流
            ByteArrayInputStream documentXmlRelsInput = this.getFreemarkerContentInputStream(u, xmlDocumentXmlRels);
            //获取 header1.xml 输入流
            ByteArrayInputStream headerInput = this.getFreemarkerContentInputStream(u, xmlHeader);
            //获取 [Content_Types].xml 输入流
            ByteArrayInputStream contentTypesInput = this.getFreemarkerContentInputStream(u, xmlContentTypes);
            //获取 document.xml 输入流
            ByteArrayInputStream documentInput = this.getFreemarkerContentInputStream(u, xmlDocument);
    
            
            File docxFile = new File(realTemplatePath + separator + docxTemplateFile);
            if (!docxFile.exists()) {
                docxFile.createNewFile();
            }
    
            ZipFile zipFile = new ZipFile(docxFile);
            Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
            File tempPath = new File(outputPath);
            //如果输出目标文件夹不存在,则创建
            if (!tempPath.exists()) {
                tempPath.mkdirs();
            }
            ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(outputPath + outputFileName));
    
            //------------------覆盖文档------------------
            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()));
                    //写入图片配置类型
                    if (next.getName().equals("[Content_Types].xml")) {
                        this.writeOutputStream(contentTypesInput, zipout, buffer, len);
                    } else if (next.getName().indexOf("document.xml.rels") > 0) {
                        //写入填充数据后的主数据配置信息
                        this.writeOutputStream(documentXmlRelsInput, zipout, buffer, len);
                    } else if ("word/document.xml".equals(next.getName())) {
                        //写入填充数据后的主数据信息
                        this.writeOutputStream(documentInput, zipout, buffer, len);
                    } else if ("word/header1.xml".equals(next.getName())) {
                        //写入填充数据后的页眉信息
                        this.writeOutputStream(headerInput, zipout, buffer, len);
                    } else {
                        while ((len = is.read(buffer)) != -1) {
                            zipout.write(buffer, 0, len);
                        }
                        is.close();
                    }
                }
            }
    
            //------------------写入新图片------------------
            len = -1;
    		if(StringUtils.isNotBlank(u.getCoverImg())) {
    			this.writeImage("image1.jpeg", u.getCoverImg(), zipout, buffer);
    		}
    		
    		if(StringUtils.isNotBlank(u.getQrCode())) {
    			this.writeImage("image2.jpeg", u.getQrCode(), zipout, buffer);
    		}
    		
    		if(StringUtils.isNotBlank(u.getGoogleMap())) {
                this.writeImage("image3.jpeg", u.getGoogleMap(), zipout, buffer);
    		}
    		
    		if(CollectionUtils.isNotEmpty(u.getDayDetail())) {
    			for(int i = 1;i<= u.getDayDetail().size() ; i++) {
    				TripDetailDTO tripDetail = u.getDayDetail().get(i-1);
    				if(CollectionUtils.isNotEmpty(tripDetail.getContents())) {
    					for(int j = 1; j<= tripDetail.getContents().size(); j++) {
    						TripContentDTO tripContent = tripDetail.getContents().get(j-1);
    						if(StringUtils.isNotBlank(tripContent.getUrl())) {
    							writeImage("image" + i + j + ".png", tripContent.getUrl() , zipout, buffer);
    						}
    					}
    				}
    			}
    		}
    		
    	    zipout.close();
    	    
    		return filePathAlias + outputFileTempPath + urlFileName;
    	}
    private void writeImage(String imageName, String path, ZipOutputStream zipout, byte[] buffer) throws Exception {
    		int len = -1;
    		ZipEntry next = new ZipEntry("word" + separator + "media" + separator + imageName);
            // 创建URL
            URL url = new URL(path);
            // 创建链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            InputStream in = conn.getInputStream();
    		 
            zipout.putNextEntry(new ZipEntry(next.toString()));
            while ((len = in.read(buffer)) != -1) {
                zipout.write(buffer, 0, len);
            }
            
            in.close();
    	}
    	
    	public ByteArrayInputStream getFreemarkerContentInputStream(Object dataMap, String templateName) throws Exception {
            //获取模板
            Template template = configuration.getTemplate(templateName);
            StringWriter swriter = new StringWriter();
            //生成文件
            template.process(dataMap, swriter);
            ByteArrayInputStream in = new ByteArrayInputStream(swriter.toString().getBytes());
            return in;
    	}
    	
    	private void writeOutputStream(ByteArrayInputStream input, ZipOutputStream zipout , byte[] buffer, int len) throws Exception {
    		if (input != null) {
                while ((len = input.read(buffer)) != -1) {
                    zipout.write(buffer, 0, len);
                }
                input.close();
            }
    	}
    

    注意特殊字符

    • 由于freemarker在<、>、&这三个字符识别时会导致文档打不开,所以需要对文本中的这些字符需要转换
    private String transform(String str){
    		if(StringUtils.isBlank(str)) {
    			return str;
    		}
    		
    		if(str.contains("<")||str.contains(">")||str.contains("&")){
    			  str=str.replaceAll("&", "&amp;");
    			  str=str.replaceAll("<", "&lt;");
    			  str=str.replaceAll(">", "&gt;");
    		}
    	
    		return str;
    	}
    
    • 文件名如果有空格,URLEncoder.encode后空格会被转为+,可以使用
      fileName = fileName.replaceAll("\+","%20");

    以上再生成的word文档就是标准格式的文档了。

    展开全文
  • 最新公司委托书标准范文企业委托书格式范文一WORD文档格式.docx
  • 最新个人租房最标准合同电子版租房居住合同标准样书word排版格式.docx
  • freemarker生成的word转成PDF后,图片丢失。 所以想到将freemarker生成的xml格式的word转成标准格式的word在转成PDF。 现在不知道怎么将xml格式的...或者如何将xml格式的word转为标准word格式 求帮忙啊!谢谢
  • 最新委托借款标准委托借款合同样本WORD文件格式.docx
  • 最近使用freemarker制作...是根据xml格式生成的,手机端不支持识别,标准word格式放到notepad里是乱码, xml格式生成的doc拖进去显示的是xml格式,所以我想请问有没有方法可以把xml格式的 doc文档转换成标准格式!
  • 最新无偿借款合同借款合同书标准范本word排版格式.docx
  • 最新导游合同书导游雇佣合同标准范本word排版格式.docx
  • 最新北京租房app北京租房合同标准样书WORD文件格式.docx
  • 最新0号轻柴油轻柴油标准合约WORD文件格式.docx
  • 最新设备购买合同个人标准设备买卖合同word排版格式.docx
  • 最新软件委托开发合同标准委托设计合同WORD文件格式.docx
  • 最新浦江厂房租赁租赁标准厂房同范本WORD文档格式.docx
  • 最新无偿借款合同标准私人借款合同模板WORD文件格式.docx
  • 最新电子代理加盟标准加盟代理合同书WORD文档格式.docx
  • 最新租房合同大全标准租房热门合同样书WORD文件格式.docx
  • 最新无偿借款合同标准银行借款合同样式WORD文件格式.docx
  • 最新无偿借款合同标准保证借款合同范文word排版格式.docx
  • 最新蔬菜采购电子合同蔬菜采购合同标准范本WORD文件格式.docx
  • 最新实习就业合同模板实习就业协议标准WORD文件格式.docx
  • 最新免费劳务合同范本短期劳务合同标准范本word排版格式.docx
  • 最新个人厨师合同范本厨师聘用协议标准WORD文件格式.docx
  • 最新赠与的标准合同书WORD格式.docx
  • 最新个人正规劳动合同私企劳动标准合同书WORD文档格式.docx
  • 最新仓储合同免费模板物品仓储标准合同范本WORD文档格式.docx
  • 最新免费租房合租合租的租房标准合同书WORD文档格式.docx
  • 最新房屋买卖合同下载免费标准买卖合同样式WORD文档格式.docx
  • 最新电子版买卖合同书标准版买卖合同word排版格式.docx

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 102,172
精华内容 40,868
关键字:

word正文格式标准