场景
使用freemarker模板生成word,word文档打不开,报错信息提示“根据架构,XML数据无效”,如下图所示
原因
生成word中有特殊字符,需要对特殊字符进行处理,常见特殊字符有:<>&''等,可以根据实际情况具体分析一下
特殊字符会导致xml格式错乱
解决方法
方法一
/**
* 通过Freemaker的Configuration读取相应的ftl,配置Freemarker模板参数信息
*/
freemarkerConfig = new Configuration(Configuration.VERSION_2_3_27);
freemarkerConfig.setDefaultEncoding("UTF-8");
freemarkerConfig.setOutputFormat(XMLOutputFormat.INSTANCE);
方法二
对于容易出现特殊字符的字段,在freemarker模板中使用“?html”处理,例如:
<w:rPr>
<w:rFonts w:ascii="宋体" w:hAnsi="宋体" w:hint="eastAsia"/>
<w:sz w:val="21"/>
<w:szCs w:val="21"/>
</w:rPr>
<w:t>${fruit.result_type}</w:t>
修改成:
<w:rPr>
<w:rFonts w:ascii="宋体" w:hAnsi="宋体" w:hint="eastAsia"/>
<w:sz w:val="21"/>
<w:szCs w:val="21"/>
</w:rPr>
<w:t>${fruit.result_type?html}</w:t>
方法三
继承CommonMarkupOutputFormat类,重写格式化模板方法,实现自定义转义功能。
import freemarker.core.CommonMarkupOutputFormat;
import freemarker.core.OutputFormat;
import freemarker.core.TemplateXMLOutputModel;
import freemarker.template.utility.StringUtil;
import java.io.IOException;
import java.io.Writer;
public final class MISXMLOutputFormat extends CommonMarkupOutputFormat<TemplateXMLOutputModel> {
/**
* The only instance (singleton) of this {@link OutputFormat}.
*/
static MISXMLOutputFormat INSTANCE = new MISXMLOutputFormat();
private MISXMLOutputFormat() {
// Only to decrease visibility
}
@Override
public String getName() {
return "XML";
}
@Override
public String getMimeType() {
return "application/xml";
}
@Override
public void output(String textToEsc, Writer out) throws IOException {
XMLOrHTMLEnc(textToEsc, out);
}
@Override
public String escapePlainText(String plainTextContent) {
return StringUtil.XMLEnc(plainTextContent);
}
@Override
public boolean isLegacyBuiltInBypassed(String builtInName) {
return builtInName.equals("xml");
}
@Override
protected TemplateXMLOutputModel newTemplateMarkupOutputModel(String plainTextContent, String markupContent) {
return null;
}
private void XMLOrHTMLEnc(String s, Writer out) throws IOException{
// 替换&
s = s.replace("&", "&");
// 替换<
s = s.replace("<", "<");
// 替换>
s = s.replace(">", ">");
// 替换单引号'
s = s.replace("'", "'");
// 替换双引号"
s = s.replace("\"", """);
s = s.replace("\r\n", "<w:br/>");
s = s.replace("\n", "<w:br/>");
s = s.replace(" ", " ");
s = s.replace("\t", "        ");
char[] aChar = s.toCharArray();
out.write(aChar);
}
}