【⼲货】java使⽤xml⽅式快速⽣成word
【⼲货】java使⽤xml⽅式快速⽣成word
为什么不使⽤POI呢?
对于这个问题,我想⼤家都有共同的见解:POI对于word的⽀持实在是太差了!
在我参与的⼀个项⽬中,我负责做⼀个根据模板⽂件,从数据库中提取相应的数据,⽣成⼀个word⽂件的模块,但是在我使⽤poi时候,我发现我没有办法将⽂字和所其中穿插的图⽚放到同⼀个模板标签中,所以我第⼀想法就是:先替换标签,再填充数据呗!可是通过实际验证,发现我的想法错了。
在第⼀步替换新的模板标签的时候,我发现,它们依然是⾪属于同⼀Paragraph的,⽽所带来的问题就是,填充数据的时候,虽然能将⽂字和图⽚填充进去,但是他们是⾪属于同⼀Paragraph,所以最终结果就是格式混乱,所有⽂字都在图⽚的上边。
那么我只要把每个标签都放在⼀个新的段落,就可以了啊!怎么弄呢。。。有了!在word中,换⾏就是⼀个新的段落了啊!!nice,这就开始做!换⾏好像是\n,试⼀下,不⾏!\r\n,不⾏,在wps中,\r\n可以被解析为换⾏,但是在office word中,却不⾏!那怎么办,要不直接添加⼀个换⾏吧!
不知所措的我,查了查百度,有⼈说通过在字符串中添加 (char)11 就可以换⾏了,试了⼀下,还是不⾏。。。再百度⼀下,poi对word有软回车和硬回车nice!!
但是在实际撸码中,才发现,这俩好像对于我的需求没啥⽤啊。。。
对POI⼼灰意冷的我,发现了,可以通过xml来⽣成word … …
如何使⽤
⾸先,就是在制作模板了,打开我⼿上的word模板,另存为xml格式!对于如何制作,⼤体上我是以下的思路:
1. ⽐对空⽂档和空⽂档添加⼀个⽂字段落,通过⽐较出段落的样式
2. ⽐对空⽂档和空⽂档添加⼀个图⽚段落,通过⽐较出图⽚段落的格式
3. ⽐对空⽂档和插⼊两个段落,通过⽐较出多个段落的排列结构
⾸先到⽂字的段落吧!
通过⽐对,发现,在xml中,⽂字的段落是如下格式的:
<w:r>
<w:rPr>
<w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast" />
<w:lang w:val="EN-US" w:fareast="ZH-CN" />
</w:rPr>
<w:t>其实,在⽣活中,⼈们。。。</w:t>
</w:r>
哈哈,到⽂字啦!!
那么如果有多个段落呢再看!!!
<w:ind w:right="340" w:right-chars="162" w:first-line="420" />
<w:rPr>
<w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast" />
<w:lang w:val="EN-US" w:fareast="ZH-CN" />
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast" />
<w:lang w:val="EN-US" w:fareast="ZH-CN" />
</w:rPr>
<w:t>其实,在⽣活中,⼈们。。。</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:ind w:right="340" w:right-chars="162" w:first-line="420" />
<w:rPr>
<w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast" />
<w:lang w:val="EN-US" w:fareast="ZH-CN" />
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast" />
<w:lang w:val="EN-US" w:fareast="ZH-CN" />
</w:rPr>
<w:t>还有很多的事情</w:t>
</w:r>
</w:p>java xml是什么
我去!不对啊!怎么跟我刚才的不⼀样原来, <w:p>标签才是word中代表⼀个段落的标签!! 所以之后的寻也明确了,重点看<w:p>!!
然后通过⽐对,我也到了图⽚的标签(过程就省略了,直接上标签!):
<w:ind w:right="340" w:right-chars="162" />
<w:jc w:val="center" /><w:rPr><w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:fareast="宋体" w:hint="fareast" />
<w:lang w:val="EN-US" w:fareast="ZH-CN" />
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:fareast="宋体" w:hint="fareast" />
<w:lang w:val="EN-US" w:fareast="ZH-CN" />
</w:rPr>
<w:pict>
<w:binData w:name="wordml://1.jpg">此处为图⽚的base64编码</w:binData>
<v:shape id="图⽚ 3" o:spid="_x0000_s1033" o:spt="75" alt="timg" type="#_x0000_t75" style="heigh
t:282.6pt;width:288pt;" filled="f" o:preferrelative="t" str oked="f" coordsize="21600,21600">
<v:path />
<v:fill on="f" focussize="0,0" />
<v:stroke on="f" />
<v:imagedata src="wordml://1.jpg" o:title="timg" />
<o:lock v:ext="edit" aspectratio="t" />
<w10:wrap type="none" />
<w10:anchorlock />
</v:shape>
</w:pict>
</w:r>
</w:p>
注意:
1.图⽚中标明“此处为图⽚的base64编码”的位置,是⽤于存放图⽚经过base64编码后的字符串的!如何将图⽚编码为base64字符串,请⾃⾏百度(很简单)!
2. 关于两个图⽚的src “wordml://1.jpg”,其中的图⽚名称不可以重复!⼤家编码的时候注意更改⼀下!
现在,只需要通过把原先的段落位置改变为模板标签,通过对我上述的标签的拼接,然后替换掉模板标签,再将xml转换成word就⼤功告成啦
⽣成word的代码
* @Title: createWord
* @Description: TODO  将数据添加到xml中,并⽣成word⽂件
* @param: map  需要替换数据的map
* @param: templateName  模板名称
* @param filePath      想要⽣成的⽂件的路径
* @param fileName      想要⽣成的⽂件的名字
* @return: String    返回⽣成⽂件地址
* @throws
*/
public static String createWord(Map map, String templateName, String filePath, String fileName) {      try {
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
// 默认将模板放置在p包下
configuration.setClassForTemplateLoading(WordUtils.class, "\\com\\wrg\\temp\\");
Template template = Template(templateName);
File outFile = new File(filePath + File.separator + fileName);
if (!ParentFile().exists()) {
}
Writer out = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(outFile), "UTF-8"));
template.process(map, out);
out.flush();
out.close();
return filePath + File.separator + fileName;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
如果⼤家有什么问题,欢迎联系我啊!如果有什么问题,也希望⼤家批评指正!
email:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。