仅分享思路:
目前个人遇到了两种生成word的方式方法,分成业务不同。
1.一种是利用最底层的apache-poi手动解析导入的word数据将所有结构、样式、文本数据存储数据库本地化,然后数据可以做页面呈现和修改,并且导出的时候可以利用修改后的数据进行导出,这种方式会涉及到很多word的样式问题,还有一些特殊的编码问题会造成特殊的科学符号没法显示的问题。
2.一种是现在公司遇到的通过html的方式,用脚本构建一个html的文本表格,利用区块对的形式把数据填充到word文档中,最后使用libreoffice对word内容做刷新,生成目录、表格、文本。
反思:第二种方式可以完美的避开word生成过程中遇到的特殊样式问题。
两种方式都对其中的XWPFDocument的类属性进行了处理,如果是定制化word的开发基本都要借助网上对word的解析工具对word进行符合自己业务的处理,仅供参考,因为每次遇到word生成基本都要自己解析,希望大家在处理word生成的时候可以想到更好的办法分享出来
//这是我之前用第一种方式处理的word信息片段展示,在这里贴出来希望这些基本属性可以有用
private static void extracted(XWPFDocument xwpf, List<LibDocumentCell> wordTableCellList, int i1) {
List<XWPFRun> runs = xwpf.getParagraphs().get(i1).getRuns();
for (int size = runs.size(); size > 0; size--) {
//删除源文档中的段落
xwpf.getParagraphs().get(i1).removeRun(0);
//剩余最后一个文档后开始替换段落
if (size == 1) {
String text = wordTableCellList.get(i1).getCellTextContent();
//位置数组,为了不同位置设置
String[] split = text.split("\n", -1);
//段落对齐方式
String location = wordTableCellList.get(i1).getAttributeFontLocation();
//对齐方式数组
String[] splitLocation = location.split(",", -1);
//段落首行缩进
String indent = wordTableCellList.get(i1).getAttributeIndent();
//首行缩进数组
String[] splitIndent = indent.split(",", -1);
//段落悬挂缩进
String hangingIndent = wordTableCellList.get(i1).getAttributeHangingIndent();
//悬挂缩进数组
String[] splitHangingIndent = hangingIndent.split(",", -1);
//段落左侧缩进
String leftIndent = wordTableCellList.get(i1).getAttributeLeftIndent();
//左侧缩进数组
String[] splitLeftIndent = leftIndent.split(",", -1);
//段落右侧缩进
String rightIndent = wordTableCellList.get(i1).getAttributeRightIndent();
//右侧缩进数组
String[] splitRightIndent = rightIndent.split(",", -1);
//段落行间距规则
String rowRule = wordTableCellList.get(i1).getAttributeRowRule();
//行间距规则数组
String[] splitRowRule = rowRule.split(",", -1);
//段落行间距
String rowVal = wordTableCellList.get(i1).getAttributeRowVal();
//行间距数组
String[] splitRowVal = rowVal.split(",", -1);
//段落段前行间距
String rowBeforeVal = wordTableCellList.get(i1).getAttributeRowBeforeVal();
//段前行间距数组
String[] splitRowBeforeVal = rowBeforeVal.split(",", -1);
//段落段后行间距
String rowAfterVal = wordTableCellList.get(i1).getAttributeRowAfterVal();
//段后行间距数组
String[] splitRowAfterVal = rowAfterVal.split(",", -1);
//段落编号
String numId = wordTableCellList.get(i1).getAttributeNumId();
//编号数组
String[] splitNumId = {};
if (numId != null) {
splitNumId = numId.split(",", -1);
}
for (int i = 0; i < split.length; i++) {
XWPFParagraph newParagraph = xwpf.getParagraphs().get(i1);
addParagraphStyle(newParagraph, i, splitLocation, splitIndent, splitHangingIndent, splitLeftIndent, splitRightIndent,
splitRowRule, splitRowVal, splitRowBeforeVal, splitRowAfterVal, splitNumId);
//获取在线编辑文档段落的文本集合
List<CellStyle> csList = FormUtil.stringToXml(split[i]);
if (csList != null && csList.size() == 1 && "".equals(csList.get(0).getValue())) {
CellStyle cellStyle = csList.get(0);
CTParaRPr ctParaRPr = newParagraph.getCTP().getPPr().addNewRPr();
if (cellStyle.getFontFamily() != null) {
CTFonts fonts = ctParaRPr.addNewRFonts();
fonts.setAscii(cellStyle.getFontFamily());
}
if (cellStyle.getFontSize() != null) {
String fs = cellStyle.getFontSize();
fs = fs.replace("px", "");
if (Double.parseDouble(fs) != 14.0) {
CTHpsMeasure ctHpsMeasure = ctParaRPr.addNewSz();
ctHpsMeasure.setVal(BigInteger.valueOf((long) (Double.parseDouble(fs) * 72 / 96)));
}
}
} else {
for (int j = 0; j < csList.size(); j++) {
CellStyle cellStyle = csList.get(j);
XWPFRun run = newParagraph.createRun();
// run.addBreak();
if (cellStyle.getPastePic() == 1) {
addBase64Picture(run, cellStyle);
} else if (cellStyle.getPastePic() == 2) {
//根据图片id查询图片数据
LibDocumentPicture picture = SpringContextUtils.getBean(LibDocumentPictureMapper.class).selectById(cellStyle.getValue());
try {
run.setFontFamily(initFontFamily);
run.addPicture(new ByteArrayInputStream(picture.getImgData()), Document.PICTURE_TYPE_PNG, "", MyUnits.pxToEMU(picture.getImgWidth()), MyUnits.pxToEMU(picture.getImgHeigh()));
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
//判断特殊字符
if (cellStyle.getSpecialCode() != null) {
StringBuilder stringBuf = new StringBuilder(cellStyle.getSpecialCode());
String s = stringBuf.replace(0, 1, "0").toString();
String s1 = unicodeToString("\\u" + s);
run.setText(s1, 0);
addStyle(run, cellStyle);
} else {
run.setText(cellStyle.getValue()
.replace("&", "&")
.replace("<", "<")
.replace(">", ">"), 0);
addStyle(run, cellStyle);
}
}
}
}
}
}
}
}