该类主要是用程序来读取word文本,并拿到你想要的内容, 我这里主要是解析一道完整的数学试题, 包括(题目,选项,答案,考点,分析,解答,点评)等内容
package com.ilike.poi;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.PicturesTable;
import org.apache.poi.hwpf.usermodel.CharacterRun;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.Range;
import com.ilike.utils.RandomNameUtil;
/**
*
*
* 实现思路:
* 1.先逐字读取整个word文档,并替换里面的图片,回车符,空格符等内容
* 2.将替换后的文本做初次切割,切出含有题目,选项,答案等内容的片段,封装成一个map集合
* 3.将初次切割后的内容片段拿来做二次切割(调用相应的切割方法进行切割),切出自己想要的内容
*
* @author 桑伟东
*
* 注意:这个切割只实现了简单的读写,读取的2的平方这样的数据依旧有问题,但会很快在下一次发表时实现
*/
public class WordToHtml7 {
public static String readFile = "F:\\doc_test\\swdTest1.doc";//要解析的文档
public static String outPath = "F:\\temp_image\\";//文档中图片的存储路径
public static String ziful = "【";//文档中含有的符号
public static String zifur = "】";//文档中含有的符号
private static final short ENTER_ASCII = 13;// 回车符
private static final short SPACE_ASCII = 32;// 空格
private static final short KONGGE_ASCII = 9;// 空格是9(这个空格是我自己调试程序发现的,正规的空格对应的编码应该是32)
public static void main(String[] args) throws Exception {
//1.替换图片及回车符等
String html = replacePhotoAndEnter(readFile);
//2.初次切割
Map<String, String> map = splitItems(html);
//3.二次切割
secondSplit(map);
}
/**
* 读取word文本,替换里面的图片以及空格,回车符等 说明:将图片替换成相应的image标签,将空格替换成 ,将回车符替换成</br>
*
* @param fileName
* 需要替换的文件
* @return 替换后的字符串文本
* @throws Exception
*/
public static String replacePhotoAndEnter(String fileName) throws Exception {
// 1.创建字节输入流读取要解析的文档
FileInputStream in = new FileInputStream(new File(fileName));
// 2.创建文档对象
HWPFDocument doc = new HWPFDocument(in);
// 3.取得文档中字符的总数
int length = doc.characterLength();
// 4.获取PicturesTable对象
PicturesTable pTable = doc.getPicturesTable();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
Range range = new Range(i, i + 1, doc);
CharacterRun cr = range.getCharacterRun(0);
// System.out.println(cr.text()+"------"+(short)(cr.text().charAt(0)));
// 1.判断该字符是否是照片
if (pTable.hasPicture(cr)) {
// 是照片
Picture pic = pTable.extractPicture(cr, false);
String file = outPath + RandomNameUtil.getRandomName6N() + ".png";
// 创建一个输出流
OutputStream out = new FileOutputStream(file);
// 将图片写出去
pic.writeImageContent(out);
// 替换图片
String webPath = "<image src='" + file + "'/>";
sb.append(webPath);
// 2.判断该字符是否是回车符,如果是就用<br/>替换
} else if (cr.text().charAt(0) == ENTER_ASCII) {
sb.append("<br/>");
// 3.判断该字符是否是空格符,如果是用 替换
} else if (cr.text().charAt(0) == SPACE_ASCII) {
sb.append(" ");
// 4.判断该字符是否是空格符,如果是用 替换(非正规替换)
} else if (cr.text().charAt(0) == KONGGE_ASCII) {
sb.append(" ");
// 5.如果所有的这些都不是,默认为普通文本
} else {
sb.append(cr.text());
}
}
return sb.toString();
}
/**
* 该方法将替换后的文本做初次切割,切割出含有想要内容的粗糙文本(含有不想要的内容), 最后封装成一个map返回
*
* @param src
* 初次切割的文本
* @return
*/
public static Map<String, String> splitItems(String src) {
Map<String, String> map = new HashMap<String, String>();
// 1.获取“【答案】”的位置
Integer answerPoi = src.indexOf("【答案】");
// 2.截取包含测试题的内容,并保存输出
String test = src.substring(0, answerPoi);
map.put("test", test);
// System.out.println("test:"+test);
// 3.获取【考点】的位置
Integer keyPoi = src.indexOf("【考点】");
// 4.截取包含答案的内容,并保存输出
String answer = src.substring(answerPoi, keyPoi);
map.put("answer", answer);
// System.out.println("answer:"+answer);
// 5.获取【分析】的位置
Integer analysePoi = src.indexOf("【分析】");
// 6.截取包含考点的内容,并保存输出
String keys = src.substring(keyPoi, analysePoi);
map.put("keys", keys);
// System.out.println("keys:"+keys);
// 7.获取【解答】的位置
Integer jiedaPoi = src.indexOf("【解答】");
// 8.截取包含分析的内容,并保存输出
String analyse = src.substring(analysePoi, jiedaPoi);
map.put("analyse", analyse);
// System.out.println("analyse:"+analyse);
// 9.获取【点评】的位置
Integer commentPoi = src.indexOf("【点评】");
// 10.截取包含考点的内容,并保存输出
String jieda = src.substring(jiedaPoi, commentPoi);
map.put("jieda", jieda);
// System.out.println("jieda:"+jieda);
// 11.截取包含点评的内容,并保存输出
String comment = src.substring(commentPoi, src.length());
map.put("comment", comment);
// System.out.println("comment:"+comment);
return map;
}
/**
* 对初次剪切后的各种文本进行二次深加工,切出真正想要的内容 如果要封装成相应的Bean,在这里就可以封装,这个较为简单,不再赘述
*
* @param map
* 初次切割后的文本
*/
public static void secondSplit(Map<String, String> map) {
for (String item : map.keySet()) {
if (item.equals("test")) {
// 是题目,调用题目剪切方法进行切割
String test = testSplit(map.get("test"));
System.out.println("test:" + test);
// 这里面也含有选项,顺带切出选项
String option = optionSplit(map.get("test"));
System.out.println("option:" + option);
} else if (item.equals("answer")) {
// 是答案,调用答案剪切方法进行切割
String answer = answerSplit(map.get("answer"));
System.out.println("answer:" + answer);
} else if (item.equals("keys")) {
// 是考点,调用考点剪切方法进行切割
String keys = keysSplit(map.get("keys"));
System.out.println("keys:" + keys);
} else if (item.equals("analyse")) {
// 是分析,调用分析剪切方法进行切割
String analyse = analyseSplit(map.get("analyse"));
System.out.println("analyse:" + analyse);
} else if (item.equals("comment")) {
// 是点评,调用点评剪切方法进行切割
String comment = commentSplit(map.get("comment"));
System.out.println("comment:" + comment);
} else if (item.equals("jieda")) {
// 是解答,调用解答剪切方法进行切割
String jieda = jiedaSplit(map.get("jieda"));
System.out.println("jieda:" + jieda);
} else {
System.out.println("未知的东东");
}
}
}
/**
* 从含有题目的文本剪切出题目
*
* @param srcTest
* @return
*/
private static String testSplit(String srcTest) {
// 1.获取"一.选择题"的位置
Integer pesition1 = srcTest.indexOf("一.选择题");
// 2.获取"A."的位置
Integer pesition2 = srcTest.indexOf("A.");
// 3.切出题目
String testtext = srcTest.substring(pesition1, pesition2);
// System.out.println("test:"+testtext);
// 4.获取第一个和最后一个“<br/>”的位置
testtext = testtext.substring(testtext.indexOf("<br/>") + "<br/>".length(), testtext.lastIndexOf("<br/>"));
// System.out.println("test:"+testtext);
return testtext;
}
/**
* 从含有选项的文本里切出选项
*
* @param srcOption
* @return
*/
private static String optionSplit(String srcOption) {
// 1.获取"A."的位置
Integer pesition1 = srcOption.indexOf("A.");
// 2.获取最后一个“<br/>”的位置
Integer pesition2 = srcOption.lastIndexOf("<br/");
// 3.切出option的内容
String option = srcOption.substring(pesition1, pesition2);
// System.out.println("option:"+option);
return option;
}
/**
* 从含有答案的文本里切出选项
*
* @param srcOption
* @return
*/
// answer:【答案】D<br/>
private static String answerSplit(String answerSrc) {
// 1.获取"【答案】"的位置
Integer pesition1 = answerSrc.indexOf("【答案】");
// 2.获取最后一个“<br/>”的位置
Integer pesition2 = answerSrc.lastIndexOf("<br/");
// 3.切出answer的内容
String answer = answerSrc.substring(pesition1, pesition2);
// System.out.println("answer:"+answer);
return answer;
}
/**
* 从含有考点的文本里切出选项
*
* @param srcOption
* @return
*/
// keys:【考点】4C:完全平方公式.菁优网版权所有<br/>
private static String keysSplit(String keysSrc) {
// 1.获取"【考点】"的位置
Integer pesition1 = keysSrc.indexOf("【考点】");
// 2.获取最后一个“<br/>”的位置
Integer pesition2 = keysSrc.lastIndexOf("<br/");
// 3.切出keys的内容
String keys = keysSrc.substring(pesition1, pesition2);
// System.out.println("keys:"+keys);
return keys;
}
/**
* 从含有分析的文本里切出选项
*
* @param srcOption
* @return
*/
// analyse:【分析】首先把a2+b2+c2﹣ab﹣bc﹣ac变为<image
// src='F:\temp_image\72d4db.png'/>(2a2+2b2+2c2﹣2ab﹣2bc﹣2ac),然后利用完全平方公式变为三个完全平方式,然后代入已知数据即可求解.<br/>
private static String analyseSplit(String analyseSrc) {
// 1.获取"【分析】"的位置
Integer pesition1 = analyseSrc.indexOf("【分析】");
// 2.获取最后一个“<br/>”的位置
Integer pesition2 = analyseSrc.lastIndexOf("<br/");
// 3.切出analyse的内容
String analyse = analyseSrc.substring(pesition1, pesition2);
// System.out.println("analyse:"+analyse);
return analyse;
}
/**
* 从含有解答的文本里切出选项
*
* @param srcOption
* @return
*/
// jieda:【解答】解:∵a2+b2+c2﹣ab﹣bc﹣ac<br/>=<image
// src='F:\temp_image\1c1dde.png'/>(2a2+2b2+2c2﹣2ab﹣2bc﹣2ac)<br/>=<image
// src='F:\temp_image\829ed0.png'/>[(a2﹣2ab+b2)+(b2﹣2bc+c2)+ (c2﹣2ac+a2)]<br/>=<image
// src='F:\temp_image\e7ded0.png'/>[(a﹣b)2+(b﹣c)2+(c﹣a)2]<br/>而a=2000x+2001,b=2000x+2002,c=2000x+2003,<br/>∴a﹣b=2000x+2002﹣(2000x+2001)=1,<br/>同理 b﹣c=﹣1,c﹣a=2,<br/>∴a2+b2+c2﹣ab﹣bc﹣ac<br/>=<image
// src='F:\temp_image\ee910f.png'/>[(a﹣b)2+(b﹣c)2+(c﹣a)2]<br/>=3.<br/>故选D.<br/>
private static String jiedaSplit(String jiedaSrc) {
// 1.获取"【解答】"的位置
Integer pesition1 = jiedaSrc.indexOf("【解答】");
// 2.获取最后一个“<br/>”的位置
Integer pesition2 = jiedaSrc.lastIndexOf("<br/");
// 3.切出jieda的内容
String jieda = jiedaSrc.substring(pesition1, pesition2);
// System.out.println("jieda:"+jieda);
return jieda;
}
/**
* 从含有点评的文本里切出选项
*
* @param srcOption
* @return
*/
// comment:【点评】此题主要考查了利用完全平方公式进行代数式变形,然后求复杂代数式的值,解题的关键是把所求代数式变形,从而大大简化计算过程.题目难度比较大.<br/><br/>
private static String commentSplit(String commentSrc) {
// 1.获取"【点评】"的位置
Integer pesition1 = commentSrc.indexOf("【点评】");
// 2.获取最后一个“<br/>”的位置
Integer pesition2 = commentSrc.lastIndexOf("<br/");
// 3.切出comment的内容
String comment = commentSrc.substring(pesition1, pesition2);
// System.out.println("comment:"+comment);
return comment;
}
}