请先阅读前期博文以便更好理解本篇博文
需要安装一个第三方公式插件建
先来分析一下xml
XWPFRun
对象
Excel
也可以是一个
PPT
等等)
style
属性,这里
style
就是图片在
Word中显示的宽高
注意:
xml中ProgID="Equation.AxMath"
属性标记着是使用的什么第三方插件(我用的是 AxMath, MathType的此属性为ProgID="Equation.DSMT4"
)
说了这么多估计还是迷糊的,下面上代码跟着代码的思路再去好好的捋一捋。
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
<w:noProof/>
w:rPr>
<w:t xml:space="preserve">公式前的文字 w:t>
w:r>
<w:r w:rsidR="00D23F9D" w:rsidRPr="0051191A">
<w:rPr>
<w:noProof/>
<w:position w:val="-10"/>
w:rPr>
<w:object w:dxaOrig="912" w:dyaOrig="318" w14:anchorId="3B58962C">
<v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
<v:stroke joinstyle="miter"/>
<v:formulas>
<v:f eqn="if lineDrawn pixelLineWidth 0"/>
<v:f eqn="sum @0 1 0"/>
<v:f eqn="sum 0 0 @1"/>
<v:f eqn="prod @2 1 2"/>
<v:f eqn="prod @3 21600 pixelWidth"/>
<v:f eqn="prod @3 21600 pixelHeight"/>
<v:f eqn="sum @0 0 1"/>
<v:f eqn="prod @6 1 2"/>
<v:f eqn="prod @7 21600 pixelWidth"/>
<v:f eqn="sum @8 21600 0"/>
<v:f eqn="prod @7 21600 pixelHeight"/>
<v:f eqn="sum @10 21600 0"/>
v:formulas>
<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
<o:lock v:ext="edit" aspectratio="t"/>
v:shapetype>
<v:shape id="_x0000_i1025" type="#_x0000_t75" style="width:45.75pt;height:15.75pt" o:ole="">
<v:imagedata r:id="rId6" o:title=""/>
v:shape>
<o:OLEObject Type="Embed" ProgID="Equation.AxMath" ShapeID="_x0000_i1025" DrawAspect="Content" ObjectID="_1626856759" r:id="rId7"/>
w:object>
w:r>
@Test
public void test4() throws Exception {
XWPFDocument word = new XWPFDocument(new FileInputStream("D:\\Test\\word\\test1.docx"));
try {
List<XWPFParagraph> paragraphs = word.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
StringBuffer text = new StringBuffer();
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
Node runNode = run.getCTR().getDomNode();
text.append(getText(runNode));
String math = getMath(run, runNode);
text.append(math);
}
System.out.println("段落内容:".concat(text.toString()));
}
} finally {
word.close();
}
}
/**
* 获取字符串
*
* @param runNode
* @return
*/
private String getText(Node runNode) {
Node textNode = getChildNode(runNode, "w:t");
if (textNode == null) {
return "";
}
return textNode.getFirstChild().getNodeValue();
}
private String getMath(XWPFRun run, Node runNode) throws Exception {
Node objectNode = getChildNode(runNode, "w:object");
if (objectNode == null) {
return "";
}
Node shapeNode = getChildNode(objectNode, "v:shape");
if (shapeNode == null) {
return "";
}
Node imageNode = getChildNode(shapeNode, "v:imagedata");
if (imageNode == null) {
return "";
}
Node binNode = getChildNode(objectNode, "o:OLEObject");
if (binNode == null) {
return "";
}
XWPFDocument word = run.getDocument();
NamedNodeMap shapeAttrs = shapeNode.getAttributes();
// 图片在Word中显示的宽高
String style = shapeAttrs.getNamedItem("style").getNodeValue();
System.out.println("图片宽高:".concat(style));
System.out.println("--------------");
NamedNodeMap imageAttrs = imageNode.getAttributes();
// 图片在Word中的ID
String imageRid = imageAttrs.getNamedItem("r:id").getNodeValue();
// 获取图片信息
PackagePart imgPart = word.getPartById(imageRid);
System.out.println("图片名称".concat(imgPart.getPartName().getName()));
System.out.println(imgPart.getInputStream());
System.out.println("--------------");
NamedNodeMap binAttrs = binNode.getAttributes();
// 公式二进制文件在Word中的ID
String binRid = binAttrs.getNamedItem("r:id").getNodeValue();
// 获取二进制文件
PackagePart binPart = word.getPartById(binRid);
System.out.println("二进制文件名称:".concat(binPart.getPartName().getName()));
System.out.println(binPart.getInputStream());
System.out.println("--------------");
return "{公式#}";
}
private Node getChildNode(Node node, String nodeName) {
if (!node.hasChildNodes()) {
return null;
}
NodeList childNodes = node.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
if (nodeName.equals(childNode.getNodeName())) {
return childNode;
}
childNode = getChildNode(childNode, nodeName);
if (childNode != null) {
return childNode;
}
}
return null;
}
@Test
public void test5() throws Exception {
XWPFDocument word = new XWPFDocument();
OutputStream stream = null;
try {
XWPFParagraph paragraph = word.createParagraph();
XWPFRun run = paragraph.createRun();
XWPFDocument doc = run.getDocument();
InputStream imgIs = new FileInputStream("D:\\Test\\word\\image1.wmf");
InputStream binIs = new FileInputStream("D:\\Test\\word\\oleObject1.bin");
org.w3c.dom.Document document = createMathType(doc, imgIs, binIs, "width:45.75pt;height:15.75pt");
// 将公式写入run中
run.setEmbossed(true);
run.getCTR().set(XmlObject.Factory.parse(document.getDocumentElement(), POIXMLTypeLoader.DEFAULT_XML_OPTIONS));
stream = new FileOutputStream("D:\\Test\\word\\test5.docx");
word.write(stream);
} finally {
word.close();
if (stream != null) {
stream.close();
}
}
}
private org.w3c.dom.Document createMathType(XWPFDocument doc, InputStream imgIs, InputStream binIs, String style)
throws Exception {
// 添加图片获取rid
String imgRid = doc.addPictureData(imgIs, Document.PICTURE_TYPE_WMF);
int rid = Integer.parseInt(imgRid.replaceAll("[a-zA-Z]", ""));
// 添加二进制文件
final PackagePartName partName = PackagingURIHelper.createPartName("/word/embeddings/oleMath" + rid + ".bin");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(IOUtils.toByteArray(binIs));
doc.getPackage().createPart(partName, "application/vnd.openxmlformats-officedocument.oleObject", bos);
PackageRelationship prOle = doc.getPackagePart().addRelationship(partName, TargetMode.INTERNAL,
POIXMLDocument.OLE_OBJECT_REL_TYPE);
// 创建xml
String xml = createObjectXml(imgRid, prOle.getId(), rid, style);
InputSource is1 = new InputSource(new StringReader(xml));
return DocumentHelper.readDocument(is1);
}
private String createObjectXml(String imgRid, String binRid, int num, String style) {
String shapeId = "math".concat(String.valueOf(num));
StringBuffer xml = new StringBuffer();
xml.append(");
xml.append("xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"\n\t");
xml.append("xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n\t");
xml.append("xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\n\t");
xml.append("xmlns:v=\"urn:schemas-microsoft-com:vml\">\n\t");
xml.append(").append(shapeId);
xml.append("\" o:ole=\"\" style=\"").append(style).append("\" type=\"\">\n\t");
xml.append(").append(imgRid).append("\" o:title=\"\" />\n\t");
xml.append(" \n\t");
xml.append(");
xml.append(shapeId);
xml.append("\" Type=\"Embed\" r:id=\"").append(binRid).append("\"/>");
xml.append(" ");
return xml.toString();
}
如果有什么不明白的可以留言。
欢迎大家留言讨论。