这个网站本来是已经做好了的 但是客户不满意需要对他进行从新架构
首先来说说用到技术 docx4j 做的核心
服务器是用的 libreoffice
前台是通过背景的方式嵌套进去的
首先来说说步骤
用户上传文档(docx)-----》后台解析成题目--------》返回给用户-------》用户选择---------》试题入库
老师前台选题 ---------》后台根据选择的题目进行解析--------》生成题号-----------》生成新的word文档返回给用户
通过docx4j 可以根据关键字分割word文档 但是分割后的文档没有图片,这个时候就需要把图片也添加上去
最后是组合word 这个部分我还是用的我docx4j来做的
以下是代码
package cn.ym.util;
import cn.ym.pojo.Aproblem;
import cn.ym.pojo.Filedoc;
import org.apache.commons.io.IOUtils;
import org.docx4j.Docx4J;
import org.docx4j.Docx4jProperties;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.HTMLSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.contenttype.ContentType;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.*;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.relationships.Relationships;
import org.docx4j.wml.CTAltChunk;
import org.docx4j.wml.Document;
import org.junit.jupiter.api.Test;
import javax.xml.bind.JAXBException;
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Docx {
/**
* 分解docx
* @param file docx的路径 file.getFilepath
* @param path 分解后的存放路径
* @return
* @throws Docx4JException
*/
public static List DivisionDocx(Filedoc file, String path)throws Docx4JException {
File file1 =new File(path);
if (!file1.exists()) file1.mkdirs();
WordprocessingMLPackage load = WordprocessingMLPackage.load(new File(file.getFilepath()));
List content = load.getMainDocumentPart().getContent();
WordprocessingMLPackage word = WordprocessingMLPackage.createPackage();
List list =new ArrayList<>();
int x = -1;
int y = -1;
for (int i =0; i < content.size(); i++) {
if (content.get(i).toString().trim().startsWith("${题目}")) {
if (x == -1) {
word.getMainDocumentPart().addObject(content.get(i));
x++;
}else {
File f =new File(path, x +"——题目.docx");
String s = f.getAbsolutePath().replaceFirst("docx","jpg");
Aproblem aproblem =new Aproblem();
aproblem.setBody(s);
aproblem.setAnswer(f.getAbsolutePath());
aproblem.setDate(new Date());
aproblem.setFiledocId(file.getId());
list.add(x, aproblem);
addimg(load, word);
word.save(f);
convertJPG(f.getAbsolutePath(),f.getParent());
word = WordprocessingMLPackage.createPackage();
word.getMainDocumentPart().addObject(content.get(i));
x++;
}
}else if (content.get(i).toString().trim().startsWith("${答案}")) {
if (y == -1) {
File f =new File(path, x +"——题目.docx");
String s = f.getAbsolutePath().replaceFirst("docx","jpg");
Aproblem aproblem =new Aproblem();
aproblem.setBody(s);
aproblem.setDate(new Date());
aproblem.setFiledocId(file.getId());
list.add(x, aproblem);
addimg(load, word);
word.save(f);
convertJPG(f.getAbsolutePath(),f.getParent());
word = WordprocessingMLPackage.createPackage();
word.getMainDocumentPart().addObject(content.get(i));
y++;
}else {
try {
File f =new File(path, y +"——答案.docx");
String s = f.getAbsolutePath().replaceFirst("docx","jpg");
list.get(y).setAnalysis(s);
addimg(load, word);
word.save(f);
word = WordprocessingMLPackage.createPackage();
word.getMainDocumentPart().addObject(content.get(i));
convertJPG(f.getAbsolutePath(),f.getParent());
y++;
}catch (Exception e){
System.out.println(e.getLocalizedMessage());
}
}
}else {
word.getMainDocumentPart().addObject(content.get(i));
}
}
try {
File f =new File(path, y +"——答案.docx");
String s = f.getAbsolutePath().replaceFirst("docx","jpg");
list.get(y).setAnalysis(s);
addimg(load, word);
word.save(f);
convertJPG(f.getAbsolutePath(),f.getParent());
}catch (Exception e){
System.out.println(e.getLocalizedMessage());
}
return list;
}
/**
*
* @param load 有资源带图片
* @param word 无资源不带图片
* @throws Docx4JException
*/
public static void addimg(WordprocessingMLPackage load, WordprocessingMLPackage word)throws Docx4JException {
RelationshipsPart part = load.getMainDocumentPart().getRelationshipsPart();
System.out.println(part);
String xml = word.getMainDocumentPart().getXML();
for (Map.Entry entry : load.getParts().getParts().entrySet()) {
if (entry.getValue()instanceof BinaryPartAbstractImage) {
BinaryPartAbstractImage binImg = (BinaryPartAbstractImage) entry.getValue();
Relationship re = binImg.getSourceRelationships().get(0);
if (xml.contains(re.getId())) {
//Relationship re = load.getMainDocumentPart().getRelationshipsPart().getRelationshipByID(id);
System.out.println(re);
PartName partName =new PartName("/word/" + re.getTarget());
System.out.println(partName.getURI());
BinaryPart oPart = (BinaryPart) load.getParts().getParts().get(new PartName("/word/" + re.getTarget()));
BinaryPart bPart =new BinaryPart(partName);
bPart.setBinaryData(oPart.getBytes());
bPart.setContentType(new ContentType(oPart.getContentType()));
bPart.setRelationshipType(re.getType());
Relationship newRe = word.getMainDocumentPart().addTargetPart(bPart);
newRe.setId(re.getId());
newRe.setType(re.getType());
}
}
}
}
/***
* 和并docx
* @param main 和并后的docx
* @param bytes 需要合并的docx的字节数组
* @param chunkId 需要合并的docx的id(最好唯一)
*/
public static void insertDocx(MainDocumentPart main,byte[] bytes,int chunkId) {
try {
AlternativeFormatInputPart afiPart =new AlternativeFormatInputPart(new PartName("/part" + chunkId +".docx"));
afiPart.setBinaryData(bytes);
Relationship altChunkRel = main.addTargetPart(afiPart);
CTAltChunk chunk = Context.getWmlObjectFactory().createCTAltChunk();
chunk.setId(altChunkRel.getId());
main.addObject(chunk);
}catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @param word 更新题目
* @param file
* @return
*/
public static File gx(WordprocessingMLPackage word,File file,int x) {
String xml = word.getMainDocumentPart().getXML();
Pattern tm = Pattern.compile("\\$\\{题目\\}");
Matcher tm_m = tm.matcher(xml);
while (tm_m.find()) {
xml = xml.replaceFirst("\\$\\{题目\\}", x +".");
xml = xml.replaceFirst("\\$\\{答案\\}", x +".");
}
try {
if (file==null)file=File.createTempFile("tmp",".docx");
Object o = XmlUtils.unmarshalString(xml);
WordprocessingMLPackage aPackage = WordprocessingMLPackage.createPackage();
MainDocumentPart mainDocumentPart = aPackage.getMainDocumentPart();
mainDocumentPart.setJaxbElement((Document)o);
word.addTargetPart(mainDocumentPart);
//if (!file.exists())file.createNewFile()
word.save(file);
WordprocessingMLPackage load = WordprocessingMLPackage.load(file);
addimg(word,load);
load.save(file);
}catch (Exception e) {
e.printStackTrace();
}
return file;
}
@Test
public void main()throws Exception {
String path="/usr/local/data/";
String s ="/usr/local/data/54e978e7-8ae1-4b30-aff2-40edb5e661a0/2——题目.docx".replaceAll("\\\\","/").replaceFirst(path,"/file/");
System.out.println(s);
/* File file = new File("C:\\Users\\user\\Desktop\\新建 DOCX 文档.docx");
File f = new File("E:\\6——答案.docx");
WordprocessingMLPackage load = WordprocessingMLPackage.load(file);
Relationship rId1 = load.getRelationshipsPart().getRelationshipByID("rId5");
System.out.println(rId1);
WordprocessingMLPackage word = WordprocessingMLPackage.load(f);
addimg(load,word);*/
// convertDocxToHtml("D:\\2019年03月28日xx学校高中数学试卷(1).docx","C:\\Users\\user\\Desktop\\线性回归分析—非线性问题2.html");
/* Filedoc filedoc = new Filedoc();
filedoc.setFilepath("C:\\Users\\user\\Desktop\\线性回归分析—非线性问题2.docx");
File file = new File("D:\\2019年03月27日xx学校高中数学试卷.docx");
WordprocessingMLPackage load = WordprocessingMLPackage.load(file);
List content = load.getMainDocumentPart().getContent();
File f = new File("C:\\Users\\user\\Desktop\\数学.docx");*/
//gx(load,f);
/* String str="";
Pattern compile = Pattern.compile("\\$.*?\\{.*?答.*?案.*?\\}");
Matcher matcher = compile.matcher(str);
System.out.println(matcher.find());*/
/*String path="E:/Files/a853ce73ab70a35195b8f624976f8bf4/a853ce73ab70a35195b8f624976f8bf4线性回归分析—非线性问题2.docx";
System.out.println(path.replaceFirst("E:/Files/","/file/"));*/
/* filedoc.setId(1);
DivisionDocx(filedoc,"E:\\");*/
}
/***
* linux 上面的一个offer转换工具
* @param path
* @param dir
*/
public static void convertJPG(String path,String dir){
String s="/usr/bin/soffice --headless --convert-to jpg "+path+" --outdir " + dir;
for (int i =0; i <4; i++) {
try {
System.out.println(s);
Process exec = Runtime.getRuntime().exec(s);
BufferedReader br =new BufferedReader(new InputStreamReader(exec.getErrorStream()));
String line;
while ((line = br.readLine()) !=null) {
//执行结果加上回车
System.out.println("info________________________line:" + line);
}
int status = exec.waitFor();
System.out.println("info------------------------status" + status);
exec.destroy();
exec =null;
if (status ==0)break;
}catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
然后是如何显示的问题 首先为了保密和保护版权 我不赞成把word转成html 因为那样保密性太差了稍微有点能力都都可以还原出来,我的观点是吧word转成图片,这样不仅保密好而且免去了处理wmf的步骤 因为这个东西如果自己写可能回花很长时间所以 我这里是借助了一个工具 libreoffice
大家可以看一下这篇文章
https://blog.csdn.net/hczjb/article/details/85066090
不过这还不行 主要是差一个文件 大家可以根据提示 去新建一下这文件 然后就可以用了