最近接到了院长让我研究word转html的课题,并要求转换完成之后加以优化,形成一个较为美观可供阅读的界面。比较头疼,完全没有接触过处理过word文档的类,也算是一次锻炼吧。接下来简单整理一下我的处理步骤。
处理步骤:
1.将小说word文档批量转换成html文件。
2.对转换后的html文件进行处理,统一字体等。
3.利用JavaScript对文档进行自动分页处理。
因为是要批量,所以不对word进行原件操作,全程用Java对word进行处理。在网上找了很久,虽然POI对word文档的支持很不友好,但是对于目前的需求是足够的。
1.展示需要用到的jar包
有一些包可能是我在测试时没有删掉,因此多余,不过最多就几个,没有什么关系。
2.编写Java文件
话不多说,直接上文件
分别用了两个方法,一个用来转换格式,一个用来对转换后html文件进行处理。
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.jsoup.Jsoup;
import org.w3c.dom.Document;
public class WordToHtml {
public static void main(String[] args) {
try {
converToHtml("F:\\test\\围城书评.doc", "f:\\test\\html\\围城书评-test.html");
} catch (Exception e) {
e.printStackTrace();
}
}
// 输出html文件
public static void outFile(String content, String path) {
FileOutputStream fos = null;
BufferedWriter bw = null;
org.jsoup.nodes.Document doc = Jsoup.parse(content);
String styleOld = doc.getElementsByTag("style").html();
// 统一字体格式为宋体
styleOld = styleOld.replaceAll("font-family:.+(?=;\\b)", "font-family:SimSun");
String c = doc.body().html();
// 对html中body标签内容进行处理,便于使JavaScript文件生效
doc.getElementsByTag("body").empty();
// 加入导入JavaScript文件的代码
doc.getElementsByTag("body").append("<div id=\"frame\">" + c + "</div><div id=\"divPagenation\"></div><div id=\"divContent\"></div><script type=\"text/javascript\" src=\"page.js\"></script>");
doc.getElementsByTag("head").empty();
doc.getElementsByTag("head").append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"></meta>");
doc.getElementsByTag("head").append(" <style type=\"text/css\"></style>");
// 加入导入样式文件的代码
doc.getElementsByTag("head").append("<link rel=\"stylesheet\" type=\"text/css\" href=\"page.css\">");
doc.getElementsByTag("style").append(styleOld);
/* 正则表达式查询字体内容:font-family:.+(?=;\b) */
// System.out.println(content);
content = doc.html();
content = content.replace("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">",
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"></meta>");
try {
File file = new File(path);
fos = new FileOutputStream(file);
bw = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
bw.write(content);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fos != null)
fos.close();
} catch (IOException ie) {
}
}
}
// word 转 html
public static void converToHtml(String fileName, String outPutFile) throws TransformerException, IOException, ParserConfigurationException {
HWPFDocument wordDocument = new HWPFDocument(new FileInputStream(fileName));
// WordToHtmlUtils.loadDoc(new FileInputStream(inputFile));
// 兼容2007 以上版本
// XSSFWorkbook xssfwork=new XSSFWorkbook(new FileInputStream(fileName));
WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
wordToHtmlConverter.setPicturesManager(new PicturesManager() {
public String savePicture(byte[] content, PictureType pictureType, String suggestedName, float widthInches,float heightInches) {
return "test/" + suggestedName;
}
});
wordToHtmlConverter.processDocument(wordDocument);
// 保存图片
List pics = wordDocument.getPicturesTable().getAllPictures();
if (pics != null) {
for (int i = 0; i < pics.size(); i++) {
Picture pic = (Picture) pics.get(i);
System.out.println();
try {
// 图片保存路径
pic.writeImageContent(new FileOutputStream("f:/test/" + pic.suggestFullFileName()));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Document htmlDocument = wordToHtmlConverter.getDocument();
ByteArrayOutputStream out = new ByteArrayOutputStream();
DOMSource domSource = new DOMSource(htmlDocument);
StreamResult streamResult = new StreamResult(out);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
serializer.setOutputProperty(OutputKeys.ENCODING, "gbk");
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.setOutputProperty(OutputKeys.METHOD, "HTML");
serializer.transform(domSource, streamResult);
out.close();
outFile(new String(out.toByteArray()), outPutFile);
}
}
样式文件 page.css
这个随便看看就好了
*
{
font-size: 15.2pt;
font-family:SimSun;
line-height: 150%;
}
.divContent
{
border: 1px solid red;
background-color: #FFD2D3;
width: 70%;
word-break: break-all;
margin: 10px 0px 10px;
padding: 10px;
}
#divContent,#divPagenation{
margin-left: 15%;
}
JavaScript文件——自动分页处理
利用JavaScript进行自动分页处理,可以不用java对html文件格式进行操作,就比较简单,就是需要JavaScript文件需要写很多东西。
var s = document.getElementById('frame').innerHTML;
//对img标签进行匹配
var imgReg = /(<img\s+src='\S+'\s*(\/)?>)/gi;
matchContent = s.match(imgReg);
imgContent = s;
if(imgReg.test(s))
{
//将img标签替换为*
imgContent = s.replace(imgReg,"*");
}
// 封装DHTMLpagenation
function DHTMLpagenation(content)
{
this.content=content; // 内容
this.contentLength=imgContent.length; // 内容长度
this.pageSizeCount; // 总页数
this.perpageLength= 100; //default perpage byte length.
this.currentPage=1; // 起始页为第1页
//this.regularExp=/.+[\?\&]{1}page=(\d+)/;
this.regularExp=/\d+/; // 建立正则表达式,匹配数字型字符串。
this.divDisplayContent;
this.contentStyle=null;
this.strDisplayContent="";
this.divDisplayPagenation;
this.strDisplayPagenation="";
// 把第二个参数赋给perpageLength;
arguments.length==2 ? perpageLength = arguments[1] : '';
try {
//创建要显示的DIV
divExecuteTime=document.createElement("DIV");
document.body.appendChild(divExecuteTime);
}
catch(e)
{
}
// 得到divPagenation容器。
if(document.getElementById("divPagenation"))
{
divDisplayPagenation=document.getElementById("divPagenation");
}
else
{
try
{
//创建分页信息
divDisplayPagenation=document.createElement("DIV");
divDisplayPagenation.id="divPagenation";
document.body.appendChild(divDisplayPagenation);
}
catch(e)
{
return false;
}
}
// 得到divContent容器
if(document.getElementById("divContent"))
{
divDisplayContent=document.getElementById("divContent");
}
else
{
try
{
//创建每页显示内容的消息的DIV
divDisplayContent=document.createElement("DIV");
divDisplayContent.id="divContent";
document.body.appendChild(divDisplayContent);
}
catch(e)
{
return false;
}
}
DHTMLpagenation.initialize();
return this;
};
//初始化分页;
//包括把加入CSS,检查是否需要分页
DHTMLpagenation.initialize=function()
{
divDisplayContent.className= contentStyle != null ? contentStyle : "divContent";
if(contentLength<=perpageLength)
{
strDisplayContent=content;
divDisplayContent.innerHTML=strDisplayContent;
return null;
}
pageSizeCount=Math.ceil((contentLength/perpageLength));
DHTMLpagenation.goto(currentPage);
DHTMLpagenation.displayContent();
};
//显示分页栏
DHTMLpagenation.displayPage=function()
{
strDisplayPagenation="分页:";
if(currentPage && currentPage !=1)
{
strDisplayPagenation+='<a href="javascript:void(0)" οnclick="DHTMLpagenation.previous()">上一页</a> ';
}
else
{
strDisplayPagenation+="上一页 ";
}
for(var i=1;i<=pageSizeCount;i++)
{
if(i!=currentPage)
{
strDisplayPagenation+='<a href="javascript:void(0)" οnclick="DHTMLpagenation.goto('+i+');">'+i+'</a> ';
}
else
{
strDisplayPagenation+=i+" ";
}
}
if(currentPage && currentPage!=pageSizeCount)
{
strDisplayPagenation+='<a href="javascript:void(0)" οnclick="DHTMLpagenation.next()">下一页</a> ';
}
else
{
strDisplayPagenation+="下一页 ";
}
strDisplayPagenation+="共 " + pageSizeCount + " 页,每页" + perpageLength + " 字符,调整字符数:<input type='text' value='"+perpageLength+"' id='ctlPerpageLength' /><input type='button' value='确定' οnclick='DHTMLpagenation.change()' />";
divDisplayPagenation.innerHTML=strDisplayPagenation;
};
//上一页
DHTMLpagenation.previous=function()
{
DHTMLpagenation.goto(currentPage-1);
};
//下一页
DHTMLpagenation.next=function()
{
DHTMLpagenation.goto(currentPage+1);
};
//跳转至某一页
DHTMLpagenation.goto=function(iCurrentPage)
{
startime=new Date();
if(regularExp.test(iCurrentPage))
{
currentPage=iCurrentPage;
var tempContent = "";
//获取当前的内容 里面包含 *
var currentContent = imgContent.substr((currentPage-1)*perpageLength,perpageLength);
tempContent = currentContent;
//当前页是否有 * 获取最后一个 * 的位置
var indexOf = currentContent.indexOf("*");
if(indexOf >= 0)
{
//获取从开始位置到当前页位置的内容
var beginToEndContent = imgContent.substr(0,currentPage*perpageLength);
//获取开始到当前页位置的内容 中的 * 的最后的下标
var reCount = beginToEndContent.split("*").length - 1;
var contentArray = currentContent.split("*");
tempContent = replaceStr(contentArray,reCount,matchContent);
}
// else
// {
// tempContent=imgContent.substr((currentPage-1)*perpageLength,perpageLength);
// }
strDisplayContent=tempContent;
}
else
{
alert("页面参数错误");
}
DHTMLpagenation.displayPage();
DHTMLpagenation.displayContent();
};
//显示当前页内容
DHTMLpagenation.displayContent=function()
{
divDisplayContent.innerHTML=strDisplayContent;
};
//改变每页的字节数
DHTMLpagenation.change=function()
{
var iPerpageLength = document.getElementById("ctlPerpageLength").value;
if(regularExp.test(iPerpageLength))
{
// DHTMLpagenation.perpageLength=iPerpageLength;
// DHTMLpagenation.currentPage=1;
// DHTMLpagenation.initialize();
DHTMLpagenation(s,iPerpageLength);
}
else
{
alert("请输入数字");
}
};
/* currentArray:当前页以 * 分割后的数组
replaceCount:从开始内容到当前页的内容 * 的个数
matchArray : img标签的匹配的内容
*/
function replaceStr(currentArray,replaceCount,matchArray)
{
var result = "";
for(var i=currentArray.length -1,j = replaceCount-1 ;i>=1; i--)
{
var temp = (matchArray[j] + currentArray[i]);
result = temp + result;
j--;
}
result = currentArray[0] + result ;
return result;
}
DHTMLpagenation(s,3000);
好啦,到这里就基本完成了,以后有功能改进会再次更新。