|
@@ -1,18 +1,36 @@
|
|
package com.qmth.cqb.utils.word;
|
|
package com.qmth.cqb.utils.word;
|
|
|
|
|
|
-import com.qmth.cqb.utils.CommonUtils;
|
|
|
|
-import com.qmth.cqb.utils.enums.QuesUnit;
|
|
|
|
-import freemarker.template.Configuration;
|
|
|
|
-import freemarker.template.Template;
|
|
|
|
-import net.sf.saxon.TransformerFactoryImpl;
|
|
|
|
-import net.sourceforge.jeuclid.LayoutContext;
|
|
|
|
-import net.sourceforge.jeuclid.context.LayoutContextImpl;
|
|
|
|
-import net.sourceforge.jeuclid.context.StyleAttributeLayoutContext;
|
|
|
|
-import net.sourceforge.jeuclid.converter.Converter;
|
|
|
|
|
|
+import java.io.BufferedWriter;
|
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.FileInputStream;
|
|
|
|
+import java.io.FileOutputStream;
|
|
|
|
+import java.io.InputStream;
|
|
|
|
+import java.io.OutputStream;
|
|
|
|
+import java.io.OutputStreamWriter;
|
|
|
|
+import java.io.StringReader;
|
|
|
|
+import java.io.StringWriter;
|
|
|
|
+import java.io.Writer;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.HashSet;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+import java.util.Set;
|
|
|
|
+import java.util.UUID;
|
|
|
|
+
|
|
|
|
+import javax.xml.bind.JAXBElement;
|
|
|
|
+import javax.xml.parsers.DocumentBuilder;
|
|
|
|
+import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
|
+import javax.xml.transform.Transformer;
|
|
|
|
+import javax.xml.transform.TransformerFactory;
|
|
|
|
+import javax.xml.transform.dom.DOMSource;
|
|
|
|
+import javax.xml.transform.stream.StreamResult;
|
|
|
|
+import javax.xml.transform.stream.StreamSource;
|
|
|
|
+
|
|
import org.apache.commons.codec.binary.Base64;
|
|
import org.apache.commons.codec.binary.Base64;
|
|
import org.apache.commons.io.FileUtils;
|
|
import org.apache.commons.io.FileUtils;
|
|
import org.apache.commons.io.IOUtils;
|
|
import org.apache.commons.io.IOUtils;
|
|
-import org.apache.commons.lang3.RandomUtils;
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.docx4j.Docx4J;
|
|
import org.docx4j.Docx4J;
|
|
import org.docx4j.TraversalUtil;
|
|
import org.docx4j.TraversalUtil;
|
|
@@ -34,75 +52,92 @@ import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
|
|
import org.docx4j.openpackaging.parts.relationships.Namespaces;
|
|
import org.docx4j.openpackaging.parts.relationships.Namespaces;
|
|
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
|
|
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
|
|
import org.docx4j.relationships.Relationship;
|
|
import org.docx4j.relationships.Relationship;
|
|
-import org.docx4j.wml.*;
|
|
|
|
|
|
+import org.docx4j.wml.ContentAccessor;
|
|
|
|
+import org.docx4j.wml.Drawing;
|
|
|
|
+import org.docx4j.wml.ObjectFactory;
|
|
|
|
+import org.docx4j.wml.P;
|
|
|
|
+import org.docx4j.wml.R;
|
|
import org.docx4j.wml.Text;
|
|
import org.docx4j.wml.Text;
|
|
import org.dom4j.Namespace;
|
|
import org.dom4j.Namespace;
|
|
import org.dom4j.io.SAXReader;
|
|
import org.dom4j.io.SAXReader;
|
|
import org.jsoup.Jsoup;
|
|
import org.jsoup.Jsoup;
|
|
|
|
+import org.jsoup.nodes.Element;
|
|
import org.jsoup.select.Elements;
|
|
import org.jsoup.select.Elements;
|
|
import org.xml.sax.InputSource;
|
|
import org.xml.sax.InputSource;
|
|
|
|
|
|
-import javax.xml.bind.JAXBElement;
|
|
|
|
-import javax.xml.parsers.DocumentBuilder;
|
|
|
|
-import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
|
-import javax.xml.transform.Transformer;
|
|
|
|
-import javax.xml.transform.TransformerFactory;
|
|
|
|
-import javax.xml.transform.dom.DOMSource;
|
|
|
|
-import javax.xml.transform.stream.StreamResult;
|
|
|
|
-import javax.xml.transform.stream.StreamSource;
|
|
|
|
-import java.io.*;
|
|
|
|
-import java.util.*;
|
|
|
|
|
|
+import com.qmth.cqb.utils.CommonUtils;
|
|
|
|
+import com.qmth.cqb.utils.enums.QuesUnit;
|
|
|
|
+
|
|
|
|
+import freemarker.template.Configuration;
|
|
|
|
+import freemarker.template.Template;
|
|
|
|
+import net.sf.saxon.TransformerFactoryImpl;
|
|
|
|
+import net.sourceforge.jeuclid.LayoutContext;
|
|
|
|
+import net.sourceforge.jeuclid.context.LayoutContextImpl;
|
|
|
|
+import net.sourceforge.jeuclid.context.StyleAttributeLayoutContext;
|
|
|
|
+import net.sourceforge.jeuclid.converter.Converter;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * docx处理工具类
|
|
|
|
- * Created by songyue on 17/3/10.
|
|
|
|
|
|
+ * docx处理工具类 Created by songyue on 17/3/10.
|
|
*/
|
|
*/
|
|
public final class DocxProcessUtil {
|
|
public final class DocxProcessUtil {
|
|
|
|
|
|
public static final LayoutContext IMG_LAYOUT = new StyleAttributeLayoutContext(
|
|
public static final LayoutContext IMG_LAYOUT = new StyleAttributeLayoutContext(
|
|
LayoutContextImpl.getDefaultLayoutContext(), "3em", java.awt.Color.BLACK);
|
|
LayoutContextImpl.getDefaultLayoutContext(), "3em", java.awt.Color.BLACK);
|
|
|
|
+
|
|
public static final String IMG_OUT_TYPE = "image/png";
|
|
public static final String IMG_OUT_TYPE = "image/png";
|
|
|
|
+
|
|
public static final String ENCODING = "utf-8";
|
|
public static final String ENCODING = "utf-8";
|
|
|
|
+
|
|
public static final String BASE64_HEADER = "data:image/png;base64,";
|
|
public static final String BASE64_HEADER = "data:image/png;base64,";
|
|
- public static final String TEMP_FILE_IMP = CommonUtils.getTmpRootPath()+"docxImport/";
|
|
|
|
- public static final String TEMP_FILE_EXP = CommonUtils.getTmpRootPath()+"docxExport/";
|
|
|
|
- public static final String OMML2MML_XSL="OMML2MML.XSL";
|
|
|
|
- public static final String PAPER_TEMPLATE="paper_template.ftl";
|
|
|
|
- public static final String ANSWER_TEMPLATE="answer_template.ftl";
|
|
|
|
|
|
+
|
|
|
|
+ public static final String TEMP_FILE_IMP = CommonUtils.getTmpRootPath() + "docxImport/";
|
|
|
|
+
|
|
|
|
+ public static final String TEMP_FILE_EXP = CommonUtils.getTmpRootPath() + "docxExport/";
|
|
|
|
+
|
|
|
|
+ public static final String OMML2MML_XSL = "OMML2MML.XSL";
|
|
|
|
+
|
|
|
|
+ public static final String PAPER_TEMPLATE = "paper_template.ftl";
|
|
|
|
+
|
|
|
|
+ public static final String ANSWER_TEMPLATE = "answer_template.ftl";
|
|
|
|
+
|
|
public static final String DOCX_SUFFIX = ".docx";
|
|
public static final String DOCX_SUFFIX = ".docx";
|
|
- public static final String BODY_HEADER ="<w:body xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">";
|
|
|
|
- public static final String BODY_TAIL ="</w:body>";
|
|
|
|
- public static final String REL_ID_HEADER="rld";
|
|
|
|
|
|
|
|
- static{
|
|
|
|
|
|
+ public static final String BODY_HEADER = "<w:body xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">";
|
|
|
|
+
|
|
|
|
+ public static final String BODY_TAIL = "</w:body>";
|
|
|
|
+
|
|
|
|
+ public static final String REL_ID_HEADER = "rld";
|
|
|
|
+
|
|
|
|
+ static {
|
|
init();
|
|
init();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 初始化文件夹
|
|
* 初始化文件夹
|
|
*/
|
|
*/
|
|
- private static void init(){
|
|
|
|
|
|
+ private static void init() {
|
|
File temp_file_exp = new File(TEMP_FILE_EXP);
|
|
File temp_file_exp = new File(TEMP_FILE_EXP);
|
|
File temp_file_img = new File(TEMP_FILE_IMP);
|
|
File temp_file_img = new File(TEMP_FILE_IMP);
|
|
- //如果输出目标文件夹不存在,则创建
|
|
|
|
- if (!temp_file_img.exists()){
|
|
|
|
|
|
+ // 如果输出目标文件夹不存在,则创建
|
|
|
|
+ if (!temp_file_img.exists()) {
|
|
temp_file_img.mkdirs();
|
|
temp_file_img.mkdirs();
|
|
}
|
|
}
|
|
- if (!temp_file_exp.exists()){
|
|
|
|
|
|
+ if (!temp_file_exp.exists()) {
|
|
temp_file_exp.mkdirs();
|
|
temp_file_exp.mkdirs();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 获取段落的所有文本
|
|
* 获取段落的所有文本
|
|
|
|
+ *
|
|
* @param p
|
|
* @param p
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static String getPText(P p){
|
|
|
|
|
|
+ public static String getPText(P p) {
|
|
String returnText = "";
|
|
String returnText = "";
|
|
- List<Object> tList = getAllElementFromObject(p,Text.class);
|
|
|
|
- for(Object obj:tList){
|
|
|
|
- Text text = (Text)obj;
|
|
|
|
|
|
+ List<Object> tList = getAllElementFromObject(p, Text.class);
|
|
|
|
+ for (Object obj : tList) {
|
|
|
|
+ Text text = (Text) obj;
|
|
returnText += text.getValue();
|
|
returnText += text.getValue();
|
|
}
|
|
}
|
|
return returnText.trim();
|
|
return returnText.trim();
|
|
@@ -110,34 +145,35 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 校验段落中是否含有公式或图片
|
|
* 校验段落中是否含有公式或图片
|
|
|
|
+ *
|
|
* @param p
|
|
* @param p
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static boolean isNotText(P p){
|
|
|
|
- List<Object> mathList = getAllElementFromObject(p,CTOMath.class);
|
|
|
|
- List<Object> drawList = getAllElementFromObject(p,Drawing.class);
|
|
|
|
- if(mathList.size() > 0 || drawList.size() > 0){
|
|
|
|
|
|
+ public static boolean isNotText(P p) {
|
|
|
|
+ List<Object> mathList = getAllElementFromObject(p, CTOMath.class);
|
|
|
|
+ List<Object> drawList = getAllElementFromObject(p, Drawing.class);
|
|
|
|
+ if (mathList.size() > 0 || drawList.size() > 0) {
|
|
return true;
|
|
return true;
|
|
- }else{
|
|
|
|
|
|
+ } else {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 获取文档包副本(去除段落)
|
|
* 获取文档包副本(去除段落)
|
|
|
|
+ *
|
|
* @param wordMLPackage
|
|
* @param wordMLPackage
|
|
* @return
|
|
* @return
|
|
* @throws Exception
|
|
* @throws Exception
|
|
*/
|
|
*/
|
|
- public static WordprocessingMLPackage getTmpPackage(WordprocessingMLPackage wordMLPackage)
|
|
|
|
- throws Exception{
|
|
|
|
- //添加关系样式信息
|
|
|
|
|
|
+ public static WordprocessingMLPackage getTmpPackage(WordprocessingMLPackage wordMLPackage) throws Exception {
|
|
|
|
+ // 添加关系样式信息
|
|
Set<String> relationshipTypes = new HashSet<String>();
|
|
Set<String> relationshipTypes = new HashSet<String>();
|
|
relationshipTypes.add(wordMLPackage.getMainDocumentPart().getRelationshipType());
|
|
relationshipTypes.add(wordMLPackage.getMainDocumentPart().getRelationshipType());
|
|
- //深拷贝
|
|
|
|
- WordprocessingMLPackage tmpWordMlPackage = (WordprocessingMLPackage)
|
|
|
|
- PartialDeepCopy.process(wordMLPackage,relationshipTypes);
|
|
|
|
- //移除所有段落
|
|
|
|
|
|
+ // 深拷贝
|
|
|
|
+ WordprocessingMLPackage tmpWordMlPackage = (WordprocessingMLPackage) PartialDeepCopy.process(wordMLPackage,
|
|
|
|
+ relationshipTypes);
|
|
|
|
+ // 移除所有段落
|
|
initTmpPackage(tmpWordMlPackage);
|
|
initTmpPackage(tmpWordMlPackage);
|
|
|
|
|
|
return tmpWordMlPackage;
|
|
return tmpWordMlPackage;
|
|
@@ -145,62 +181,62 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 初始化文档包(去除所有段落)
|
|
* 初始化文档包(去除所有段落)
|
|
|
|
+ *
|
|
* @param wordMLPackage
|
|
* @param wordMLPackage
|
|
* @return
|
|
* @return
|
|
* @throws Exception
|
|
* @throws Exception
|
|
*/
|
|
*/
|
|
- public static void initTmpPackage(WordprocessingMLPackage wordMLPackage)
|
|
|
|
- throws Exception{
|
|
|
|
- //移除所有段落
|
|
|
|
|
|
+ public static void initTmpPackage(WordprocessingMLPackage wordMLPackage) throws Exception {
|
|
|
|
+ // 移除所有段落
|
|
List<Object> contentList = wordMLPackage.getMainDocumentPart().getContent();
|
|
List<Object> contentList = wordMLPackage.getMainDocumentPart().getContent();
|
|
contentList.removeAll(contentList);
|
|
contentList.removeAll(contentList);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 获得段落wordml
|
|
* 获得段落wordml
|
|
|
|
+ *
|
|
* @param p
|
|
* @param p
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static String getPWordMl(P p)throws Exception{
|
|
|
|
|
|
+ public static String getPWordMl(P p) throws Exception {
|
|
return XmlUtils.marshaltoString(p);
|
|
return XmlUtils.marshaltoString(p);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 转换wordMl为html
|
|
* 转换wordMl为html
|
|
|
|
+ *
|
|
* @param wordMl
|
|
* @param wordMl
|
|
* @return
|
|
* @return
|
|
* @throws Exception
|
|
* @throws Exception
|
|
*/
|
|
*/
|
|
- public static String docx2Html(String wordMl,WordprocessingMLPackage wordMLPackage)
|
|
|
|
- throws Exception{
|
|
|
|
|
|
+ public static String docx2Html(String wordMl, WordprocessingMLPackage wordMLPackage) throws Exception {
|
|
|
|
|
|
initTmpPackage(wordMLPackage);
|
|
initTmpPackage(wordMLPackage);
|
|
|
|
|
|
- //转换wordml为完整的package对象
|
|
|
|
|
|
+ // 转换wordml为完整的package对象
|
|
MainDocumentPart mdp = wordMLPackage.getMainDocumentPart();
|
|
MainDocumentPart mdp = wordMLPackage.getMainDocumentPart();
|
|
Object p = XmlUtils.unmarshalString(wordMl);
|
|
Object p = XmlUtils.unmarshalString(wordMl);
|
|
|
|
|
|
mdp.getContent().add(p);
|
|
mdp.getContent().add(p);
|
|
|
|
|
|
- //转换公式为图片
|
|
|
|
- replaceMath2Image(wordMLPackage,(P)p);
|
|
|
|
|
|
+ // 转换公式为图片
|
|
|
|
+ replaceMath2Image(wordMLPackage, (P) p);
|
|
|
|
|
|
- //设置导出临时html参数
|
|
|
|
|
|
+ // 设置导出临时html参数
|
|
HTMLSettings htmlSettings = Docx4J.createHTMLSettings();
|
|
HTMLSettings htmlSettings = Docx4J.createHTMLSettings();
|
|
htmlSettings.setImageDirPath(TEMP_FILE_IMP + "_files");
|
|
htmlSettings.setImageDirPath(TEMP_FILE_IMP + "_files");
|
|
- htmlSettings.setImageTargetUri(TEMP_FILE_IMP.substring(TEMP_FILE_IMP.lastIndexOf("/")+1)
|
|
|
|
- + "_files");
|
|
|
|
|
|
+ htmlSettings.setImageTargetUri(TEMP_FILE_IMP.substring(TEMP_FILE_IMP.lastIndexOf("/") + 1) + "_files");
|
|
htmlSettings.setWmlPackage(wordMLPackage);
|
|
htmlSettings.setWmlPackage(wordMLPackage);
|
|
String tmpHtmlPath = TEMP_FILE_IMP + UUID.randomUUID().toString() + ".html";
|
|
String tmpHtmlPath = TEMP_FILE_IMP + UUID.randomUUID().toString() + ".html";
|
|
File tmpHtml = new File(tmpHtmlPath);
|
|
File tmpHtml = new File(tmpHtmlPath);
|
|
OutputStream os = new java.io.FileOutputStream(tmpHtml);
|
|
OutputStream os = new java.io.FileOutputStream(tmpHtml);
|
|
- Docx4J.toHTML(htmlSettings,os,Docx4J.FLAG_EXPORT_PREFER_XSL);
|
|
|
|
|
|
+ Docx4J.toHTML(htmlSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
|
|
os.flush();
|
|
os.flush();
|
|
|
|
|
|
- //格式化html代码
|
|
|
|
|
|
+ // 格式化html代码
|
|
String htmlStr = formatHtmlByPath(tmpHtmlPath);
|
|
String htmlStr = formatHtmlByPath(tmpHtmlPath);
|
|
|
|
|
|
- //删除临时html文件
|
|
|
|
|
|
+ // 删除临时html文件
|
|
FileUtils.deleteQuietly(tmpHtml);
|
|
FileUtils.deleteQuietly(tmpHtml);
|
|
|
|
|
|
return htmlStr;
|
|
return htmlStr;
|
|
@@ -208,30 +244,28 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 替换所有公式为图片
|
|
* 替换所有公式为图片
|
|
|
|
+ *
|
|
* @param wordMLPackage
|
|
* @param wordMLPackage
|
|
* @throws Exception
|
|
* @throws Exception
|
|
*/
|
|
*/
|
|
- public static void replaceAllMath2Image(WordprocessingMLPackage wordMLPackage)
|
|
|
|
- throws Exception{
|
|
|
|
|
|
+ public static void replaceAllMath2Image(WordprocessingMLPackage wordMLPackage) throws Exception {
|
|
List<Object> pList = getAllElementFromObject(wordMLPackage.getMainDocumentPart(), P.class);
|
|
List<Object> pList = getAllElementFromObject(wordMLPackage.getMainDocumentPart(), P.class);
|
|
for (Object pObject : pList) {
|
|
for (Object pObject : pList) {
|
|
- P p=(P) pObject;
|
|
|
|
|
|
+ P p = (P) pObject;
|
|
List<Object> pContent = p.getContent();
|
|
List<Object> pContent = p.getContent();
|
|
int index = 0;
|
|
int index = 0;
|
|
- for(Object child:pContent){
|
|
|
|
- if(child instanceof ContentAccessor){
|
|
|
|
|
|
+ for (Object child : pContent) {
|
|
|
|
+ if (child instanceof ContentAccessor) {
|
|
index++;
|
|
index++;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- if (child instanceof JAXBElement) child = ((JAXBElement<?>)child).getValue();
|
|
|
|
|
|
+ if (child instanceof JAXBElement)
|
|
|
|
+ child = ((JAXBElement<?>) child).getValue();
|
|
if (child.getClass().equals(CTOMath.class)) {
|
|
if (child.getClass().equals(CTOMath.class)) {
|
|
- String omml = XmlUtils.marshaltoString(child, true, true,
|
|
|
|
- Context.jc,
|
|
|
|
- "http://schemas.openxmlformats.org/officeDocument/2006/math",
|
|
|
|
- "oMath", CTOMath.class);
|
|
|
|
- byte [] imgByte = convertMathml2Img(omml2mml(omml));
|
|
|
|
- pContent.set(index,
|
|
|
|
- newImage( wordMLPackage, imgByte, "math"+(index), "math"+(index)));
|
|
|
|
|
|
+ String omml = XmlUtils.marshaltoString(child, true, true, Context.jc,
|
|
|
|
+ "http://schemas.openxmlformats.org/officeDocument/2006/math", "oMath", CTOMath.class);
|
|
|
|
+ byte[] imgByte = convertMathml2Img(omml2mml(omml));
|
|
|
|
+ pContent.set(index, newImage(wordMLPackage, imgByte, "math" + (index), "math" + (index)));
|
|
}
|
|
}
|
|
index++;
|
|
index++;
|
|
}
|
|
}
|
|
@@ -240,27 +274,25 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 替换公式为图片
|
|
* 替换公式为图片
|
|
|
|
+ *
|
|
* @param p
|
|
* @param p
|
|
* @throws Exception
|
|
* @throws Exception
|
|
*/
|
|
*/
|
|
- public static void replaceMath2Image(WordprocessingMLPackage wordMLPackage,P p)
|
|
|
|
- throws Exception{
|
|
|
|
|
|
+ public static void replaceMath2Image(WordprocessingMLPackage wordMLPackage, P p) throws Exception {
|
|
List<Object> pContent = p.getContent();
|
|
List<Object> pContent = p.getContent();
|
|
int index = 0;
|
|
int index = 0;
|
|
- for(Object child:pContent){
|
|
|
|
- if(child instanceof ContentAccessor){
|
|
|
|
|
|
+ for (Object child : pContent) {
|
|
|
|
+ if (child instanceof ContentAccessor) {
|
|
index++;
|
|
index++;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- if (child instanceof JAXBElement) child = ((JAXBElement<?>)child).getValue();
|
|
|
|
|
|
+ if (child instanceof JAXBElement)
|
|
|
|
+ child = ((JAXBElement<?>) child).getValue();
|
|
if (child.getClass().equals(CTOMath.class)) {
|
|
if (child.getClass().equals(CTOMath.class)) {
|
|
- String omml = XmlUtils.marshaltoString(child, true, true,
|
|
|
|
- Context.jc,
|
|
|
|
- "http://schemas.openxmlformats.org/officeDocument/2006/math",
|
|
|
|
- "oMath", CTOMath.class);
|
|
|
|
- byte [] imgByte = convertMathml2Img(omml2mml(omml));
|
|
|
|
- pContent.set(index,
|
|
|
|
- newImage( wordMLPackage, imgByte, "math"+(index), "math"+(index)));
|
|
|
|
|
|
+ String omml = XmlUtils.marshaltoString(child, true, true, Context.jc,
|
|
|
|
+ "http://schemas.openxmlformats.org/officeDocument/2006/math", "oMath", CTOMath.class);
|
|
|
|
+ byte[] imgByte = convertMathml2Img(omml2mml(omml));
|
|
|
|
+ pContent.set(index, newImage(wordMLPackage, imgByte, "math" + (index), "math" + (index)));
|
|
}
|
|
}
|
|
index++;
|
|
index++;
|
|
}
|
|
}
|
|
@@ -268,6 +300,7 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 创建新图片
|
|
* 创建新图片
|
|
|
|
+ *
|
|
* @param wordMLPackage
|
|
* @param wordMLPackage
|
|
* @param bytes
|
|
* @param bytes
|
|
* @param filenameHint
|
|
* @param filenameHint
|
|
@@ -275,14 +308,12 @@ public final class DocxProcessUtil {
|
|
* @return
|
|
* @return
|
|
* @throws Exception
|
|
* @throws Exception
|
|
*/
|
|
*/
|
|
- public static R newImage(WordprocessingMLPackage wordMLPackage,
|
|
|
|
- byte[] bytes,
|
|
|
|
- String filenameHint, String altText) throws Exception {
|
|
|
|
- int id1=(int) ((Math.random()*1000)*(Math.random()*1000));
|
|
|
|
- int id2=(int) ((Math.random()*1000)*(Math.random()*1000));
|
|
|
|
|
|
+ public static R newImage(WordprocessingMLPackage wordMLPackage, byte[] bytes, String filenameHint, String altText)
|
|
|
|
+ throws Exception {
|
|
|
|
+ int id1 = (int) ((Math.random() * 1000) * (Math.random() * 1000));
|
|
|
|
+ int id2 = (int) ((Math.random() * 1000) * (Math.random() * 1000));
|
|
|
|
|
|
- BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.
|
|
|
|
- createImagePart(wordMLPackage,bytes);
|
|
|
|
|
|
+ BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes);
|
|
|
|
|
|
Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, false);
|
|
Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, false);
|
|
|
|
|
|
@@ -299,6 +330,7 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 获取wordMl固定节点下所有子节点
|
|
* 获取wordMl固定节点下所有子节点
|
|
|
|
+ *
|
|
* @param obj
|
|
* @param obj
|
|
* @param toSearch
|
|
* @param toSearch
|
|
* @return
|
|
* @return
|
|
@@ -306,7 +338,8 @@ public final class DocxProcessUtil {
|
|
public static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
|
|
public static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
|
|
|
|
|
|
List<Object> result = new ArrayList<Object>();
|
|
List<Object> result = new ArrayList<Object>();
|
|
- if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue();
|
|
|
|
|
|
+ if (obj instanceof JAXBElement)
|
|
|
|
+ obj = ((JAXBElement<?>) obj).getValue();
|
|
if (obj.getClass().equals(toSearch))
|
|
if (obj.getClass().equals(toSearch))
|
|
result.add(obj);
|
|
result.add(obj);
|
|
else if (obj instanceof ContentAccessor) {
|
|
else if (obj instanceof ContentAccessor) {
|
|
@@ -320,10 +353,11 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* omml转换成mml
|
|
* omml转换成mml
|
|
|
|
+ *
|
|
* @param omml
|
|
* @param omml
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static String omml2mml(String omml){
|
|
|
|
|
|
+ public static String omml2mml(String omml) {
|
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
InputStream stylesheet = ClassLoader.getSystemResourceAsStream(OMML2MML_XSL);
|
|
InputStream stylesheet = ClassLoader.getSystemResourceAsStream(OMML2MML_XSL);
|
|
StringReader sr = new StringReader(omml);
|
|
StringReader sr = new StringReader(omml);
|
|
@@ -343,7 +377,7 @@ public final class DocxProcessUtil {
|
|
transformer.transform(source, result);
|
|
transformer.transform(source, result);
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
- } finally{
|
|
|
|
|
|
+ } finally {
|
|
IOUtils.closeQuietly(sr);
|
|
IOUtils.closeQuietly(sr);
|
|
IOUtils.closeQuietly(writer);
|
|
IOUtils.closeQuietly(writer);
|
|
}
|
|
}
|
|
@@ -354,25 +388,49 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 格式化转换后的html(html字符串)
|
|
* 格式化转换后的html(html字符串)
|
|
|
|
+ *
|
|
* @param htmlStr
|
|
* @param htmlStr
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static String formatHtml(String htmlStr){
|
|
|
|
- try{
|
|
|
|
|
|
+ public static String formatHtml(String htmlStr) {
|
|
|
|
+ try {
|
|
org.jsoup.nodes.Document doc = Jsoup.parse(htmlStr);
|
|
org.jsoup.nodes.Document doc = Jsoup.parse(htmlStr);
|
|
Elements divs = doc.select("div[class='document");
|
|
Elements divs = doc.select("div[class='document");
|
|
doc.select("p").removeAttr("class").removeAttr("style");
|
|
doc.select("p").removeAttr("class").removeAttr("style");
|
|
doc.select("div").removeAttr("class").removeAttr("style");
|
|
doc.select("div").removeAttr("class").removeAttr("style");
|
|
doc.select("span").removeAttr("class").removeAttr("style");
|
|
doc.select("span").removeAttr("class").removeAttr("style");
|
|
doc.select("span").stream().forEach(element -> {
|
|
doc.select("span").stream().forEach(element -> {
|
|
- if(!element.hasText())element.remove();});
|
|
|
|
- if(divs.size() > 0){
|
|
|
|
|
|
+ if (!element.hasText())
|
|
|
|
+ element.remove();
|
|
|
|
+ });
|
|
|
|
+ if (divs.size() > 0) {
|
|
htmlStr = divs.html();
|
|
htmlStr = divs.html();
|
|
- }else{
|
|
|
|
|
|
+ } else {
|
|
htmlStr = doc.html();
|
|
htmlStr = doc.html();
|
|
}
|
|
}
|
|
return htmlStr;
|
|
return htmlStr;
|
|
- }catch(Exception e){
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return htmlStr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取html(html字符串)里面文本
|
|
|
|
+ *
|
|
|
|
+ * @param htmlStr
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static String getTextInHtml(String htmlStr) {
|
|
|
|
+ try {
|
|
|
|
+ org.jsoup.nodes.Document doc = Jsoup.parse(htmlStr);
|
|
|
|
+ String textStr = "";
|
|
|
|
+ Elements links = doc.select("p").removeAttr("img");
|
|
|
|
+ for (Element link : links) {
|
|
|
|
+ textStr += link.text();
|
|
|
|
+ }
|
|
|
|
+ return textStr;
|
|
|
|
+ } catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
return htmlStr;
|
|
return htmlStr;
|
|
@@ -380,37 +438,39 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 格式化转换后的html(html临时文件)
|
|
* 格式化转换后的html(html临时文件)
|
|
|
|
+ *
|
|
* @param htmlPath
|
|
* @param htmlPath
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static String formatHtmlByPath(String htmlPath){
|
|
|
|
|
|
+ public static String formatHtmlByPath(String htmlPath) {
|
|
String htmlStr = "";
|
|
String htmlStr = "";
|
|
File htmlFile;
|
|
File htmlFile;
|
|
- try{
|
|
|
|
|
|
+ try {
|
|
htmlFile = new File(htmlPath);
|
|
htmlFile = new File(htmlPath);
|
|
- org.jsoup.nodes.Document doc = Jsoup.parse(htmlFile,ENCODING);
|
|
|
|
|
|
+ org.jsoup.nodes.Document doc = Jsoup.parse(htmlFile, ENCODING);
|
|
Elements divs = doc.select("div[class='document']");
|
|
Elements divs = doc.select("div[class='document']");
|
|
doc.select("p").removeAttr("class").removeAttr("style");
|
|
doc.select("p").removeAttr("class").removeAttr("style");
|
|
doc.select("div").removeAttr("class").removeAttr("style");
|
|
doc.select("div").removeAttr("class").removeAttr("style");
|
|
doc.select("span").removeAttr("class").removeAttr("style");
|
|
doc.select("span").removeAttr("class").removeAttr("style");
|
|
doc.select("span").stream().forEach(element -> {
|
|
doc.select("span").stream().forEach(element -> {
|
|
- if(!element.hasText())element.remove();});
|
|
|
|
|
|
+ if (!element.hasText())
|
|
|
|
+ element.remove();
|
|
|
|
+ });
|
|
Elements imgs = doc.select("img");
|
|
Elements imgs = doc.select("img");
|
|
- for(org.jsoup.nodes.Element img:imgs){
|
|
|
|
|
|
+ for (org.jsoup.nodes.Element img : imgs) {
|
|
String imgSrc = img.attr("src");
|
|
String imgSrc = img.attr("src");
|
|
- if(!StringUtils.isEmpty(imgSrc)){
|
|
|
|
- String imgBase64 = new String(getBase64ByPath(htmlFile.getParent()
|
|
|
|
- +"/"+imgSrc));
|
|
|
|
- img.attr("src",BASE64_HEADER+imgBase64);
|
|
|
|
|
|
+ if (!StringUtils.isEmpty(imgSrc)) {
|
|
|
|
+ String imgBase64 = new String(getBase64ByPath(htmlFile.getParent() + "/" + imgSrc));
|
|
|
|
+ img.attr("src", BASE64_HEADER + imgBase64);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if(divs.size() > 0){
|
|
|
|
|
|
+ if (divs.size() > 0) {
|
|
htmlStr = divs.html();
|
|
htmlStr = divs.html();
|
|
- }else{
|
|
|
|
|
|
+ } else {
|
|
htmlStr = doc.html();
|
|
htmlStr = doc.html();
|
|
}
|
|
}
|
|
return htmlStr;
|
|
return htmlStr;
|
|
- }catch(Exception e){
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
return htmlStr;
|
|
return htmlStr;
|
|
@@ -418,23 +478,24 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 转换mathml为png图片
|
|
* 转换mathml为png图片
|
|
|
|
+ *
|
|
* @param mathMlStr
|
|
* @param mathMlStr
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static byte[] convertMathml2Img(String mathMlStr){
|
|
|
|
|
|
+ public static byte[] convertMathml2Img(String mathMlStr) {
|
|
File xmlFile = null;
|
|
File xmlFile = null;
|
|
File imgFile = null;
|
|
File imgFile = null;
|
|
FileOutputStream xmlFos = null;
|
|
FileOutputStream xmlFos = null;
|
|
byte[] base64Byte = new byte[0];
|
|
byte[] base64Byte = new byte[0];
|
|
try {
|
|
try {
|
|
- xmlFile = new File(TEMP_FILE_IMP,UUID.randomUUID().toString());
|
|
|
|
- imgFile = new File(TEMP_FILE_IMP,UUID.randomUUID().toString());
|
|
|
|
|
|
+ xmlFile = new File(TEMP_FILE_IMP, UUID.randomUUID().toString());
|
|
|
|
+ imgFile = new File(TEMP_FILE_IMP, UUID.randomUUID().toString());
|
|
xmlFos = new FileOutputStream(xmlFile);
|
|
xmlFos = new FileOutputStream(xmlFile);
|
|
IOUtils.write(mathMlStr, xmlFos, ENCODING);
|
|
IOUtils.write(mathMlStr, xmlFos, ENCODING);
|
|
xmlFos.flush();
|
|
xmlFos.flush();
|
|
Converter.getInstance().convert(xmlFile, imgFile, IMG_OUT_TYPE, IMG_LAYOUT);
|
|
Converter.getInstance().convert(xmlFile, imgFile, IMG_OUT_TYPE, IMG_LAYOUT);
|
|
base64Byte = IOUtils.toByteArray(new FileInputStream(imgFile));
|
|
base64Byte = IOUtils.toByteArray(new FileInputStream(imgFile));
|
|
- } catch(Exception e) {
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
} finally {
|
|
} finally {
|
|
IOUtils.closeQuietly(xmlFos);
|
|
IOUtils.closeQuietly(xmlFos);
|
|
@@ -446,10 +507,11 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 通过图片路径获取base64码
|
|
* 通过图片路径获取base64码
|
|
|
|
+ *
|
|
* @param imgFilePath
|
|
* @param imgFilePath
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static byte[] getBase64ByPath(String imgFilePath){
|
|
|
|
|
|
+ public static byte[] getBase64ByPath(String imgFilePath) {
|
|
InputStream is = null;
|
|
InputStream is = null;
|
|
byte[] base64Byte = new byte[0];
|
|
byte[] base64Byte = new byte[0];
|
|
byte[] imgByte;
|
|
byte[] imgByte;
|
|
@@ -458,9 +520,9 @@ public final class DocxProcessUtil {
|
|
is = new FileInputStream(imgFile);
|
|
is = new FileInputStream(imgFile);
|
|
imgByte = IOUtils.toByteArray(is);
|
|
imgByte = IOUtils.toByteArray(is);
|
|
base64Byte = Base64.encodeBase64(imgByte);
|
|
base64Byte = Base64.encodeBase64(imgByte);
|
|
- }catch(Exception e) {
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
- }finally {
|
|
|
|
|
|
+ } finally {
|
|
IOUtils.closeQuietly(is);
|
|
IOUtils.closeQuietly(is);
|
|
FileUtils.deleteQuietly(imgFile);
|
|
FileUtils.deleteQuietly(imgFile);
|
|
}
|
|
}
|
|
@@ -469,10 +531,11 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 通过图片文件获取base64码
|
|
* 通过图片文件获取base64码
|
|
|
|
+ *
|
|
* @param imgFile
|
|
* @param imgFile
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static byte[] getBase64ByFile(File imgFile){
|
|
|
|
|
|
+ public static byte[] getBase64ByFile(File imgFile) {
|
|
InputStream is = null;
|
|
InputStream is = null;
|
|
byte[] base64Byte = new byte[0];
|
|
byte[] base64Byte = new byte[0];
|
|
byte[] imgByte;
|
|
byte[] imgByte;
|
|
@@ -480,9 +543,9 @@ public final class DocxProcessUtil {
|
|
is = new FileInputStream(imgFile);
|
|
is = new FileInputStream(imgFile);
|
|
imgByte = IOUtils.toByteArray(is);
|
|
imgByte = IOUtils.toByteArray(is);
|
|
base64Byte = Base64.encodeBase64(imgByte);
|
|
base64Byte = Base64.encodeBase64(imgByte);
|
|
- }catch(Exception e) {
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
- }finally {
|
|
|
|
|
|
+ } finally {
|
|
IOUtils.closeQuietly(is);
|
|
IOUtils.closeQuietly(is);
|
|
}
|
|
}
|
|
return base64Byte;
|
|
return base64Byte;
|
|
@@ -490,76 +553,83 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 格式化段落wordml
|
|
* 格式化段落wordml
|
|
|
|
+ *
|
|
* @param pWordMl
|
|
* @param pWordMl
|
|
* @return
|
|
* @return
|
|
* @throws Exception
|
|
* @throws Exception
|
|
*/
|
|
*/
|
|
- public static String formatPWordMl(String pWordMl) throws Exception{
|
|
|
|
- String tmpWordMl = pWordMl.replaceAll("\\\\\"","\"");
|
|
|
|
|
|
+ public static String formatPWordMl(String pWordMl) throws Exception {
|
|
|
|
+ String tmpWordMl = pWordMl.replaceAll("\\\\\"", "\"");
|
|
SAXReader sax = new SAXReader();
|
|
SAXReader sax = new SAXReader();
|
|
ByteArrayInputStream is = new ByteArrayInputStream(tmpWordMl.getBytes("UTF-8"));
|
|
ByteArrayInputStream is = new ByteArrayInputStream(tmpWordMl.getBytes("UTF-8"));
|
|
org.dom4j.Document document = sax.read(is);
|
|
org.dom4j.Document document = sax.read(is);
|
|
org.dom4j.Element root = document.getRootElement();
|
|
org.dom4j.Element root = document.getRootElement();
|
|
List<Namespace> namespaces = root.additionalNamespaces();
|
|
List<Namespace> namespaces = root.additionalNamespaces();
|
|
- namespaces.stream().forEach(namespace -> {root.remove(namespace);});
|
|
|
|
|
|
+ namespaces.stream().forEach(namespace -> {
|
|
|
|
+ root.remove(namespace);
|
|
|
|
+ });
|
|
return root.asXML();
|
|
return root.asXML();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 过滤试题单元标题
|
|
* 过滤试题单元标题
|
|
|
|
+ *
|
|
* @param p
|
|
* @param p
|
|
* @param quesUnit
|
|
* @param quesUnit
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static P formatP(P p, QuesUnit quesUnit){
|
|
|
|
|
|
+ public static P formatP(P p, QuesUnit quesUnit) {
|
|
List<Object> pContent = p.getContent();
|
|
List<Object> pContent = p.getContent();
|
|
int index = 0;
|
|
int index = 0;
|
|
|
|
|
|
- for(Object child:pContent) {
|
|
|
|
- if(child.getClass().equals(R.class)){
|
|
|
|
|
|
+ for (Object child : pContent) {
|
|
|
|
+ if (child.getClass().equals(R.class)) {
|
|
|
|
|
|
- R r = (R)child;
|
|
|
|
|
|
+ R r = (R) child;
|
|
List<Object> rContent = r.getContent();
|
|
List<Object> rContent = r.getContent();
|
|
|
|
|
|
- for(Object rChild:rContent){
|
|
|
|
|
|
+ for (Object rChild : rContent) {
|
|
|
|
|
|
- rChild = ((JAXBElement<?>)rChild).getValue();
|
|
|
|
|
|
+ rChild = ((JAXBElement<?>) rChild).getValue();
|
|
|
|
|
|
- if(rChild.getClass().equals(Text.class)){
|
|
|
|
|
|
+ if (rChild.getClass().equals(Text.class)) {
|
|
++index;
|
|
++index;
|
|
- Text text = (Text)rChild;
|
|
|
|
|
|
+ Text text = (Text) rChild;
|
|
String tmpText = text.getValue();
|
|
String tmpText = text.getValue();
|
|
- if(quesUnit == QuesUnit.QUES_BODY){
|
|
|
|
- //过滤题干标题
|
|
|
|
- if(tmpText.matches("^\\d{1,}\\.[\\s\\S]*")){
|
|
|
|
- tmpText = tmpText.replaceFirst("\\d{1,}\\.","");
|
|
|
|
|
|
+ if (quesUnit == QuesUnit.QUES_BODY) {
|
|
|
|
+ // 过滤题干标题
|
|
|
|
+ if (tmpText.matches("^\\d{1,}\\.[\\s\\S]*")) {
|
|
|
|
+ tmpText = tmpText.replaceFirst("\\d{1,}\\.", "");
|
|
text.setValue(tmpText);
|
|
text.setValue(tmpText);
|
|
- }else{
|
|
|
|
- tmpText = tmpText.replaceFirst("\\d{1,}","").replaceFirst("\\.","");
|
|
|
|
|
|
+ } else {
|
|
|
|
+ tmpText = tmpText.replaceFirst("\\d{1,}", "").replaceFirst("\\.", "");
|
|
text.setValue(tmpText);
|
|
text.setValue(tmpText);
|
|
- if(index == 2)break;
|
|
|
|
|
|
+ if (index == 2)
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
|
|
- }else if(quesUnit == QuesUnit.QUES_OPTION){
|
|
|
|
- //过滤选项标题
|
|
|
|
- if(tmpText.matches("^[a-zA-Z]\\.[\\s\\S]*")){
|
|
|
|
- tmpText = tmpText.replaceFirst("[a-zA-Z]\\.","");
|
|
|
|
|
|
+ } else if (quesUnit == QuesUnit.QUES_OPTION) {
|
|
|
|
+ // 过滤选项标题
|
|
|
|
+ if (tmpText.matches("^[a-zA-Z]\\.[\\s\\S]*")) {
|
|
|
|
+ tmpText = tmpText.replaceFirst("[a-zA-Z]\\.", "");
|
|
text.setValue(tmpText);
|
|
text.setValue(tmpText);
|
|
- }else{
|
|
|
|
- tmpText = tmpText.replaceFirst("[a-zA-Z]","").replaceFirst("\\.","");
|
|
|
|
|
|
+ } else {
|
|
|
|
+ tmpText = tmpText.replaceFirst("[a-zA-Z]", "").replaceFirst("\\.", "");
|
|
text.setValue(tmpText);
|
|
text.setValue(tmpText);
|
|
- if(index == 2)break;
|
|
|
|
|
|
+ if (index == 2)
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
|
|
- }else if(quesUnit == QuesUnit.QUES_ANSWER){
|
|
|
|
- //过滤答案标题
|
|
|
|
- if(index < 4){
|
|
|
|
- tmpText = tmpText.replaceFirst("\\[|\\]","").replaceFirst("答案","");
|
|
|
|
- }else{
|
|
|
|
- tmpText = tmpText.replaceFirst("[:|:]","");
|
|
|
|
|
|
+ } else if (quesUnit == QuesUnit.QUES_ANSWER) {
|
|
|
|
+ // 过滤答案标题
|
|
|
|
+ if (index < 4) {
|
|
|
|
+ tmpText = tmpText.replaceFirst("\\[|\\]", "").replaceFirst("答案", "");
|
|
|
|
+ } else {
|
|
|
|
+ tmpText = tmpText.replaceFirst("[:|:]", "");
|
|
}
|
|
}
|
|
text.setValue(tmpText);
|
|
text.setValue(tmpText);
|
|
- if(index == 4)break;
|
|
|
|
|
|
+ if (index == 4)
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -571,100 +641,101 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 导出word
|
|
* 导出word
|
|
|
|
+ *
|
|
* @param dataMap
|
|
* @param dataMap
|
|
* @param fileName
|
|
* @param fileName
|
|
*/
|
|
*/
|
|
- public static void exportWord(Map dataMap,String fileName,String templatePath){
|
|
|
|
|
|
+ public static void exportWord(Map dataMap, String fileName, String templatePath) {
|
|
Writer out = null;
|
|
Writer out = null;
|
|
try {
|
|
try {
|
|
- //创建配置实例
|
|
|
|
|
|
+ // 创建配置实例
|
|
Configuration configuration = new Configuration(Configuration.VERSION_2_3_25);
|
|
Configuration configuration = new Configuration(Configuration.VERSION_2_3_25);
|
|
- //设置编码
|
|
|
|
|
|
+ // 设置编码
|
|
configuration.setDefaultEncoding("UTF-8");
|
|
configuration.setDefaultEncoding("UTF-8");
|
|
- //设置ftl模板路径
|
|
|
|
- configuration.setClassForTemplateLoading(DocxProcessUtil.class,"/");
|
|
|
|
- //获取模板
|
|
|
|
- Template template = configuration.getTemplate(templatePath,ENCODING);
|
|
|
|
- //输出文件
|
|
|
|
- File outFile = new File(TEMP_FILE_EXP+fileName+DOCX_SUFFIX);
|
|
|
|
-
|
|
|
|
- //将模板和数据模型合并生成文件
|
|
|
|
- out = new BufferedWriter(new OutputStreamWriter
|
|
|
|
- (new FileOutputStream(outFile),ENCODING));
|
|
|
|
- //生成文件
|
|
|
|
|
|
+ // 设置ftl模板路径
|
|
|
|
+ configuration.setClassForTemplateLoading(DocxProcessUtil.class, "/");
|
|
|
|
+ // 获取模板
|
|
|
|
+ Template template = configuration.getTemplate(templatePath, ENCODING);
|
|
|
|
+ // 输出文件
|
|
|
|
+ File outFile = new File(TEMP_FILE_EXP + fileName + DOCX_SUFFIX);
|
|
|
|
+
|
|
|
|
+ // 将模板和数据模型合并生成文件
|
|
|
|
+ out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), ENCODING));
|
|
|
|
+ // 生成文件
|
|
template.process(dataMap, out);
|
|
template.process(dataMap, out);
|
|
|
|
|
|
out.flush();
|
|
out.flush();
|
|
|
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
- }finally {
|
|
|
|
|
|
+ } finally {
|
|
IOUtils.closeQuietly(out);
|
|
IOUtils.closeQuietly(out);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 导出试卷
|
|
* 导出试卷
|
|
|
|
+ *
|
|
* @param dataMap
|
|
* @param dataMap
|
|
* @param fileName
|
|
* @param fileName
|
|
*/
|
|
*/
|
|
- public static void exportPaper(Map dataMap,String fileName){
|
|
|
|
- exportWord(dataMap,fileName,PAPER_TEMPLATE);
|
|
|
|
|
|
+ public static void exportPaper(Map dataMap, String fileName) {
|
|
|
|
+ exportWord(dataMap, fileName, PAPER_TEMPLATE);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 导出答案
|
|
* 导出答案
|
|
|
|
+ *
|
|
* @param dataMap
|
|
* @param dataMap
|
|
* @param fileName
|
|
* @param fileName
|
|
*/
|
|
*/
|
|
- public static void exportAnswer(Map dataMap,String fileName){
|
|
|
|
- exportWord(dataMap,fileName,ANSWER_TEMPLATE);
|
|
|
|
|
|
+ public static void exportAnswer(Map dataMap, String fileName) {
|
|
|
|
+ exportWord(dataMap, fileName, ANSWER_TEMPLATE);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 处理导出word中的图片
|
|
* 处理导出word中的图片
|
|
|
|
+ *
|
|
* @param fileName
|
|
* @param fileName
|
|
* @param wordMLPackages
|
|
* @param wordMLPackages
|
|
* @throws Exception
|
|
* @throws Exception
|
|
*/
|
|
*/
|
|
- public static void processImage(String fileName,
|
|
|
|
- List<WordprocessingMLPackage> wordMLPackages)
|
|
|
|
- throws Exception{
|
|
|
|
|
|
+ public static void processImage(String fileName, List<WordprocessingMLPackage> wordMLPackages) throws Exception {
|
|
|
|
|
|
- String filePath = TEMP_FILE_EXP+fileName+DOCX_SUFFIX;
|
|
|
|
|
|
+ String filePath = TEMP_FILE_EXP + fileName + DOCX_SUFFIX;
|
|
InputStream mainFile = new FileInputStream(filePath);
|
|
InputStream mainFile = new FileInputStream(filePath);
|
|
- //以单个wordXml方式解析freemarker导出的文件
|
|
|
|
|
|
+ // 以单个wordXml方式解析freemarker导出的文件
|
|
FlatOpcXmlImporter flatOpcXmlImporter = new FlatOpcXmlImporter(mainFile);
|
|
FlatOpcXmlImporter flatOpcXmlImporter = new FlatOpcXmlImporter(mainFile);
|
|
WordprocessingMLPackage wordMLPackage = (WordprocessingMLPackage) flatOpcXmlImporter.get();
|
|
WordprocessingMLPackage wordMLPackage = (WordprocessingMLPackage) flatOpcXmlImporter.get();
|
|
|
|
|
|
- for(WordprocessingMLPackage wp:wordMLPackages){
|
|
|
|
- //获取资源文件存储
|
|
|
|
|
|
+ for (WordprocessingMLPackage wp : wordMLPackages) {
|
|
|
|
+ // 获取资源文件存储
|
|
PartStore partStore = wp.getSourcePartStore();
|
|
PartStore partStore = wp.getSourcePartStore();
|
|
- //获取图片资源定义
|
|
|
|
|
|
+ // 获取图片资源定义
|
|
RelationshipsPart rp = wp.getMainDocumentPart().getRelationshipsPart();
|
|
RelationshipsPart rp = wp.getMainDocumentPart().getRelationshipsPart();
|
|
List<Relationship> rels = rp.getRelationshipsByType(Namespaces.IMAGE);
|
|
List<Relationship> rels = rp.getRelationshipsByType(Namespaces.IMAGE);
|
|
|
|
|
|
List<Part> parts = new ArrayList<Part>();
|
|
List<Part> parts = new ArrayList<Part>();
|
|
- for(Relationship relationship:rels){
|
|
|
|
|
|
+ for (Relationship relationship : rels) {
|
|
parts.add(rp.getPart(relationship));
|
|
parts.add(rp.getPart(relationship));
|
|
}
|
|
}
|
|
- //添加资源文件存储
|
|
|
|
|
|
+ // 添加资源文件存储
|
|
wordMLPackage.setSourcePartStore(partStore);
|
|
wordMLPackage.setSourcePartStore(partStore);
|
|
- //添加资源文件定义
|
|
|
|
- for(Part p:parts){
|
|
|
|
- wordMLPackage.getMainDocumentPart().addTargetPart(p,
|
|
|
|
- RelationshipsPart.AddPartBehaviour.REUSE_EXISTING,
|
|
|
|
- p.getSourceRelationship().getId());
|
|
|
|
|
|
+ // 添加资源文件定义
|
|
|
|
+ for (Part p : parts) {
|
|
|
|
+ wordMLPackage.getMainDocumentPart().addTargetPart(p, RelationshipsPart.AddPartBehaviour.REUSE_EXISTING,
|
|
|
|
+ p.getSourceRelationship().getId());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- //以word2007标准模式重新保存(zip包)
|
|
|
|
|
|
+ // 以word2007标准模式重新保存(zip包)
|
|
OutputStream os = new java.io.FileOutputStream(filePath);
|
|
OutputStream os = new java.io.FileOutputStream(filePath);
|
|
- Docx4J.save(wordMLPackage,os,Docx4J.FLAG_SAVE_ZIP_FILE);
|
|
|
|
|
|
+ Docx4J.save(wordMLPackage, os, Docx4J.FLAG_SAVE_ZIP_FILE);
|
|
IOUtils.closeQuietly(os);
|
|
IOUtils.closeQuietly(os);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 获取word二进制数据(空文档,只有样式和资源)
|
|
* 获取word二进制数据(空文档,只有样式和资源)
|
|
|
|
+ *
|
|
* @param wordMLPackage
|
|
* @param wordMLPackage
|
|
* @return
|
|
* @return
|
|
* @throws Exception
|
|
* @throws Exception
|
|
@@ -674,7 +745,7 @@ public final class DocxProcessUtil {
|
|
DocxProcessUtil.initTmpPackage(wordMLPackage);
|
|
DocxProcessUtil.initTmpPackage(wordMLPackage);
|
|
|
|
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
- Docx4J.save(wordMLPackage,outputStream);
|
|
|
|
|
|
+ Docx4J.save(wordMLPackage, outputStream);
|
|
byte[] bytes = outputStream.toByteArray();
|
|
byte[] bytes = outputStream.toByteArray();
|
|
|
|
|
|
outputStream.flush();
|
|
outputStream.flush();
|
|
@@ -684,11 +755,13 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 通过二进制流获取word文档包
|
|
* 通过二进制流获取word文档包
|
|
|
|
+ *
|
|
* @param bytes
|
|
* @param bytes
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static WordprocessingMLPackage getPkg(byte [] bytes){
|
|
|
|
- if(bytes.length == 0)return null;
|
|
|
|
|
|
+ public static WordprocessingMLPackage getPkg(byte[] bytes) {
|
|
|
|
+ if (bytes.length == 0)
|
|
|
|
+ return null;
|
|
InputStream inputStream = new ByteArrayInputStream(bytes);
|
|
InputStream inputStream = new ByteArrayInputStream(bytes);
|
|
WordprocessingMLPackage wordMLPackage = null;
|
|
WordprocessingMLPackage wordMLPackage = null;
|
|
try {
|
|
try {
|
|
@@ -701,28 +774,28 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 初始化word文档图片资源路径,防止导出试卷时资源ID冲突
|
|
* 初始化word文档图片资源路径,防止导出试卷时资源ID冲突
|
|
|
|
+ *
|
|
* @param wordMLPackage
|
|
* @param wordMLPackage
|
|
*/
|
|
*/
|
|
- public static void initPkgImage(WordprocessingMLPackage wordMLPackage){
|
|
|
|
- //获取文档中所有图片引用位置
|
|
|
|
|
|
+ public static void initPkgImage(WordprocessingMLPackage wordMLPackage) {
|
|
|
|
+ // 获取文档中所有图片引用位置
|
|
ClassFinder finder = new ClassFinder(CTBlip.class);
|
|
ClassFinder finder = new ClassFinder(CTBlip.class);
|
|
new TraversalUtil(wordMLPackage.getMainDocumentPart().getContent(), finder);
|
|
new TraversalUtil(wordMLPackage.getMainDocumentPart().getContent(), finder);
|
|
List<Object> blips = finder.results;
|
|
List<Object> blips = finder.results;
|
|
- //获取文档中所有图片引用定义
|
|
|
|
- List<Relationship> relationships =
|
|
|
|
- wordMLPackage.getMainDocumentPart()
|
|
|
|
- .getRelationshipsPart().getRelationshipsByType(Namespaces.IMAGE);
|
|
|
|
- //同步替换资源ID
|
|
|
|
|
|
+ // 获取文档中所有图片引用定义
|
|
|
|
+ List<Relationship> relationships = wordMLPackage.getMainDocumentPart().getRelationshipsPart()
|
|
|
|
+ .getRelationshipsByType(Namespaces.IMAGE);
|
|
|
|
+ // 同步替换资源ID
|
|
int index = 0;
|
|
int index = 0;
|
|
String rldHeader = getRldNum();
|
|
String rldHeader = getRldNum();
|
|
- for(Relationship relationship:relationships){
|
|
|
|
|
|
+ for (Relationship relationship : relationships) {
|
|
String tmpId = relationship.getId();
|
|
String tmpId = relationship.getId();
|
|
- for(Object obj:blips){
|
|
|
|
- if(obj.getClass().equals(CTBlip.class)){
|
|
|
|
- CTBlip ctBlip = (CTBlip)obj;
|
|
|
|
|
|
+ for (Object obj : blips) {
|
|
|
|
+ if (obj.getClass().equals(CTBlip.class)) {
|
|
|
|
+ CTBlip ctBlip = (CTBlip) obj;
|
|
String tmpEmbed = ctBlip.getEmbed();
|
|
String tmpEmbed = ctBlip.getEmbed();
|
|
- if(tmpId.equals(tmpEmbed)){
|
|
|
|
- String tmp = rldHeader +(++index);
|
|
|
|
|
|
+ if (tmpId.equals(tmpEmbed)) {
|
|
|
|
+ String tmp = rldHeader + (++index);
|
|
relationship.setId(tmp);
|
|
relationship.setId(tmp);
|
|
ctBlip.setEmbed(tmp);
|
|
ctBlip.setEmbed(tmp);
|
|
}
|
|
}
|
|
@@ -733,9 +806,10 @@ public final class DocxProcessUtil {
|
|
|
|
|
|
/**
|
|
/**
|
|
* 获取RldNum
|
|
* 获取RldNum
|
|
|
|
+ *
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public static String getRldNum(){
|
|
|
|
|
|
+ public static String getRldNum() {
|
|
return REL_ID_HEADER + CommonUtils.getCurNum();
|
|
return REL_ID_HEADER + CommonUtils.getCurNum();
|
|
}
|
|
}
|
|
|
|
|