{"id":5246,"date":"2022-05-06T22:50:01","date_gmt":"2022-05-06T14:50:01","guid":{"rendered":"https:\/\/ixyzero.com\/blog\/?p=5246"},"modified":"2022-05-06T22:50:01","modified_gmt":"2022-05-06T14:50:01","slug":"%e7%94%a8-docx4j-%e5%af%b9pptx%e6%96%87%e6%a1%a3%e8%bf%9b%e8%a1%8c%e7%ae%80%e5%8d%95%e8%af%bb%e5%86%99","status":"publish","type":"post","link":"https:\/\/ixyzero.com\/blog\/archives\/5246.html","title":{"rendered":"\u7528 docx4j \u5bf9pptx\u6587\u6863\u8fdb\u884c\u7b80\u5355\u8bfb\u5199"},"content":{"rendered":"\n<p>=Start=<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">\u7f18\u7531\uff1a<\/h4>\n\n\n\n<p>\u7b80\u5355\u8bb0\u5f55\u4e00\u4e0b\u5bf9pptx\u6587\u4ef6\u8fdb\u884c\u7b80\u5355\u8bfb\u5199\u7684\u65b9\u6cd5\uff0c\u65b9\u4fbf\u6709\u9700\u8981\u7684\u53c2\u8003\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">\u6b63\u6587\uff1a<\/h4>\n\n\n\n<h5 class=\"wp-block-heading\">\u53c2\u8003\u89e3\u7b54\uff1a<\/h5>\n\n\n\n<p>\u76f4\u63a5\u770b\u4ee3\u7801\u5427\uff0c\u7b80\u5355\u76f4\u63a5\uff0c\u5982\u679c\u5bf9OOXML\u7684\u683c\u5f0f\u89c4\u8303\u6709\u4e00\u5b9a\u4e86\u89e3\u7684\u8bdd\u7406\u89e3\u8d77\u6765\u4f1a\u66f4\u5bb9\u6613\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.example;\n\nimport org.docx4j.TraversalUtil;\nimport org.docx4j.XmlUtils;\nimport org.docx4j.dml.CTTextBody;\nimport org.docx4j.dml.CTTextParagraph;\nimport org.docx4j.openpackaging.exceptions.Docx4JException;\nimport org.docx4j.openpackaging.packages.PresentationMLPackage;\nimport org.docx4j.openpackaging.parts.PresentationML.SlidePart;\nimport org.jsoup.Jsoup;\nimport org.jsoup.nodes.Document;\nimport org.jsoup.parser.Parser;\nimport org.pptx4j.jaxb.Context;\nimport org.pptx4j.pml.Shape;\n\nimport java.io.File;\nimport java.util.List;\n\n\/**\n * @author ixyzero\n * Created on 2022-05-04\n *\/\npublic class opOfficePptx3 {\n    public static void main(String&#91;] args) {\n        String filePath = \"new-test.pptx\";\n        try {\n            PresentationMLPackage presentationMLPackage = PresentationMLPackage.load(new File(filePath));\n            \/\/ traverse pptx content\n            \/\/ printPptxContent(presentationMLPackage);\n            printPptxContentStr(presentationMLPackage);\n            \/\/ add hidden text\n            textMark(presentationMLPackage, \"test 98308\");\n            \/\/ traverse pptx content again for comparison\n            printPptxContentStr(presentationMLPackage);\n            presentationMLPackage.save(new File(\"new-test-pptx3.pptx\")); \/\/ mark then save\n        } catch (Docx4JException e) {\n            e.printStackTrace();\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return;\n    }\n\n    private static void printPptxContentStr(PresentationMLPackage pptxPackage) throws Exception {\n        String tag = \"a:t\";\n        \/\/ \u5bf9\u4e8e\u4e00\u4e2apptx\u6587\u4ef6\u6765\u8bf4\uff0c\u89e3\u538b\u4e4b\u540e\u5728 ppt\/slides\/ \u4e0b\u9762\u7684\u6bcf\u4e00\u4e2a\u6587\u4ef6 slideN.xml \u5c31\u662f\u4e00\u4e2a\u9875\u9762\uff0c\u4e5f\u662f\u4e00\u4e2a\u5355\u72ec\u7684XML\u6587\u4ef6\n        \/\/ \u6240\u4ee5\u5982\u679c\u60f3\u8981\u83b7\u53d6pptx\u4e2d\u6240\u6709\u7684\u9875\u9762\u5185\u5bb9\u7684\u8bdd\uff0c\u9700\u8981\u904d\u5386\u6bcf\u4e00\u4e2aslide\u7136\u540e\u89e3\u6790\u5e76\u63d0\u53d6\u5176\u4e2d\u7684\u7279\u5b9a\u8282\u70b9\u7684\u5185\u5bb9\n        for (int i=0; i&lt;pptxPackage.getMainPresentationPart().getSlideCount(); i++) {\n            SlidePart slide = pptxPackage.getMainPresentationPart().getSlide(i);\n            System.out.println(String.format(\"\\nthis is slide %d:\", i));\n            \/\/ traverse xml content via jsoup\n            String xmlStr = slide.getXML();\n            \/\/System.out.println(xmlStr); \/\/ print all xml content\n            Document doc = Jsoup.parse(xmlStr, \"\", Parser.xmlParser());\n            System.out.println(doc.getElementsByTag(tag)); \/\/ &lt;a:t>xxx&lt;\/a:t> \u539f\u6765\u8fd9\u4e2a\u53ebtag\u800c\u4e0d\u662fid\/css query selector\n        }\n        return;\n    }\n\n    \/\/ TraverseSlide.java (https:\/\/github.com\/plutext\/docx4j\/tree\/VERSION_11_4_6\/docx4j-samples-pptx4j)\n    private static void printPptxContent(PresentationMLPackage pptxPackage) throws Exception {\n        for (int i=0; i&lt;pptxPackage.getMainPresentationPart().getSlideCount(); i++) {\n            SlidePart slide = pptxPackage.getMainPresentationPart().getSlide(i);\n            System.out.println(String.format(\"\\nthis is slide %d:\", i));\n\n            \/\/ \u4e0b\u9762\u7684\u8fd9\u6bb5\u4ee3\u7801\u5185\u5bb9\u5176\u5b9e\u53ef\u4ee5\u7b80\u5355\u7684\u7528\u6253\u5370 slide.getXML() \u6765\u66ff\u4ee3\u2026\u2026\n            new TraversalUtil(slide.getJaxbElement().getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame(),\n                    new TraversalUtil.Callback() {\n                        String indent = \"\";\n                        \/\/ @Override\n                        public List&lt;Object> apply(Object o) {\n                            String text = \"\";\n                            try {\n                                System.out.println(indent + o.getClass().getName() + \"\\n\\n\" + XmlUtils.marshaltoString(o, true, org.pptx4j.jaxb.Context.jcPML));\n                            } catch (RuntimeException me) {\n                                System.out.println(indent + o.getClass().getName());\n                            }\n\n                            if (o instanceof org.pptx4j.pml.Shape) {\n                                CTTextBody txBody = ((org.pptx4j.pml.Shape) o).getTxBody();\n                                if (txBody != null) {\n                                    for (CTTextParagraph tp : txBody.getP()) {\n                                        System.out.println(indent + tp.getClass().getName() + \"\\n\\n\" + XmlUtils.marshaltoString(tp, true, true, org.pptx4j.jaxb.Context.jcPML,\n                                                \"http:\/\/schemas.openxmlformats.org\/presentationml\/2006\/main\", \"txBody\", CTTextParagraph.class));\n                                    }\n                                }\n                            }\n                            return null;\n                        }\n\n                        \/\/ @Override\n                        public boolean shouldTraverse(Object o) {\n                            return true;\n                        }\n\n                        \/\/ Depth first\n                        \/\/ @Override\n                        public void walkJAXBElements(Object parent) {\n                            indent += \"    \";\n                            List children = getChildren(parent);\n                            if (children != null) {\n                                for (Object o : children) {\n                                    \/\/ if its wrapped in javax.xml.bind.JAXBElement, get its\n                                    \/\/ value\n                                    o = XmlUtils.unwrap(o);\n                                    this.apply(o);\n                                    if (this.shouldTraverse(o)) {\n                                        walkJAXBElements(o);\n                                    }\n                                }\n                            }\n                            indent = indent.substring(0, indent.length() - 4);\n                        }\n\n                        \/\/ @Override\n                        public List&lt;Object> getChildren(Object o) {\n                            return TraversalUtil.getChildrenImpl(o);\n                        }\n                    }\n            );\n        }\n    }\n\n    private static void textMark(PresentationMLPackage pptxPackage, String text) throws Exception {\n        Shape shape = ((Shape) XmlUtils.unmarshalString(\n                getHiddenShape(text), Context.jcPML) );\n        for (int i = 0; i &lt; pptxPackage.getMainPresentationPart().getSlideCount(); i++) {\n            if(i % 2 == 0) {\n                SlidePart slidePart = pptxPackage.getMainPresentationPart().getSlide(i);\n                slidePart.getJaxbElement().getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame().add(shape);\n            }\n        }\n        return;\n    }\n\n    private static String getHiddenShape(String hiddenStr) {\n        return \"&lt;p:sp xmlns:a=\\\"http:\/\/schemas.openxmlformats.org\/drawingml\/2006\/main\\\" xmlns:r=\\\"http:\/\/schemas.openxmlformats.org\/officeDocument\/2006\/relationships\\\" xmlns:p=\\\"http:\/\/schemas.openxmlformats.org\/presentationml\/2006\/main\\\">\" +\n                \"&lt;p:nvSpPr>\\n\" +\n                \"&lt;p:cNvPr id=\\\"2001\\\" name=\\\"Shape 2001\\\"\/>\\n\" + \/\/ p:cNvPr -> id\/name\n                \"&lt;p:cNvSpPr txBox=\\\"true\\\"\/>\\n\" +\n                \"&lt;p:nvPr\/>\\n\" +\n                \"&lt;\/p:nvSpPr>\\n\" +\n                \"&lt;p:spPr>\\n\" +\n                \"&lt;a:xfrm>\\n\" +\n                \"&lt;a:off x=\\\"-100\\\" y=\\\"0\\\"\/>\\n\" + \/\/ a:off-x\/y\n                \"&lt;a:ext cx=\\\"16999\\\" cy=\\\"16999\\\"\/>\\n\" + \/\/ a:ext-cx\/cy\n                \"&lt;\/a:xfrm>\\n\" +\n                \"&lt;a:prstGeom prst=\\\"rect\\\">\\n\" +\n                \"&lt;a:avLst\/>\\n\" +\n                \"&lt;\/a:prstGeom>\\n\" +\n                \"&lt;\/p:spPr>\\n\" +\n                \"&lt;p:txBody>\\n\" +\n                \"&lt;a:bodyPr lIns=\\\"16158\\\" tIns=\\\"16158\\\" rIns=\\\"16158\\\" bIns=\\\"16158\\\" anchor=\\\"t\\\" anchorCtr=\\\"false\\\">\\n\" +\n                \"&lt;a:noAutofit\/>\\n\" +\n                \"&lt;\/a:bodyPr>\\n\" +\n                \"&lt;a:lstStyle\/>\\n\" +\n                \"&lt;a:p>\\n\" +\n                \"&lt;a:pPr>\\n\" +\n                \"&lt;a:spcBef>\\n\" +\n                \"&lt;a:spcPts val=\\\"0\\\"\/>\\n\" +\n                \"&lt;\/a:spcBef>\\n\" +\n                \"&lt;a:buNone\/>\\n\" +\n                \"&lt;\/a:pPr>\\n\" +\n                \"&lt;a:r>\\n\" +\n                \"&lt;a:rPr lang=\\\"en\\\" sz=\\\"100\\\" dirty=\\\"false\\\">\\n\" +\n                \"&lt;a:solidFill>\\n\" +\n                \"&lt;a:schemeClr val=\\\"lt1\\\">\\n\" +\n                \"&lt;a:alpha val=\\\"1000\\\"\/>\\n\" +\n                \"&lt;\/a:schemeClr>\\n\" +\n                \"&lt;\/a:solidFill>\\n\" +\n                \"&lt;\/a:rPr>\\n\" +\n                \"&lt;a:t>\" + hiddenStr + \"&lt;\/a:t>\\n\" +\n                \"&lt;\/a:r>\\n\" +\n                \"&lt;\/a:p>\\n\" +\n                \"&lt;\/p:txBody>\\n\" +\n                \"&lt;\/p:sp>\";\n    }\n}\n<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">\u53c2\u8003\u94fe\u63a5\uff1a<\/h5>\n\n\n\n<p>p:cNvPr -> Non-Visual Drawing Properties<br><a href=\"http:\/\/www.datypic.com\/sc\/ooxml\/e-p_cNvPr-1.html\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/www.datypic.com\/sc\/ooxml\/e-p_cNvPr-1.html<\/a><\/p>\n\n\n\n<p><strong><em>p:nvSpPr -> Non-Visual Properties for a Shape<\/em><\/strong><br><a href=\"http:\/\/www.datypic.com\/sc\/ooxml\/e-p_nvSpPr-1.html\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/www.datypic.com\/sc\/ooxml\/e-p_nvSpPr-1.html<\/a><\/p>\n\n\n\n<p>p:nvPicPr -> Non-Visual Properties for a Picture<br><a href=\"http:\/\/www.datypic.com\/sc\/ooxml\/e-p_nvPicPr-1.html\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/www.datypic.com\/sc\/ooxml\/e-p_nvPicPr-1.html<\/a><\/p>\n\n\n\n<p><strong>a:xfrm -> 2D Transform for Individual Objects<\/strong><br><a href=\"http:\/\/www.datypic.com\/sc\/ooxml\/e-a_xfrm-4.html\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/www.datypic.com\/sc\/ooxml\/e-a_xfrm-4.html<\/a><\/p>\n\n\n\n<p>a:off -> Offset (X-Axis\/Y-Axis Coordinate)<br><a href=\"http:\/\/www.datypic.com\/sc\/ooxml\/e-a_off-1.html\">http:\/\/www.datypic.com\/sc\/ooxml\/e-a_off-1.html<\/a><\/p>\n\n\n\n<p>a:ext -> Extent Length\/Width<br><a href=\"http:\/\/www.datypic.com\/sc\/ooxml\/e-a_ext-2.html\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/www.datypic.com\/sc\/ooxml\/e-a_ext-2.html<\/a><\/p>\n\n\n\n<p>=END=<\/p>\n","protected":false},"excerpt":{"rendered":"<p>=Start= \u7f18\u7531\uff1a \u7b80\u5355\u8bb0\u5f55\u4e00\u4e0b\u5bf9pptx\u6587\u4ef6\u8fdb\u884c\u7b80\u5355\u8bfb\u5199\u7684\u65b9\u6cd5\uff0c\u65b9\u4fbf\u6709\u9700\u8981\u7684\u53c2\u8003\u3002 \u6b63\u6587\uff1a \u53c2\u8003\u89e3\u7b54\uff1a  [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23,7],"tags":[1802,1807,1805,599],"class_list":["post-5246","post","type-post","status-publish","format-standard","hentry","category-knowledgebase-2","category-programing","tag-docx4j","tag-ooxml","tag-pptx","tag-xml"],"views":1913,"_links":{"self":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts\/5246","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/comments?post=5246"}],"version-history":[{"count":1,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts\/5246\/revisions"}],"predecessor-version":[{"id":5247,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts\/5246\/revisions\/5247"}],"wp:attachment":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/media?parent=5246"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/categories?post=5246"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/tags?post=5246"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}