java语言Office转html

转换工具我选OpenOffice (版本4)+ jodconverter(版本3)。跨平台,完全免费。

这两样工具网上很容易下载到,转换代码也很简单。主要的工作是对转换形成的html代码进行加工。主要目的有二:

1.修正失真

2.清理掉冗余代码

处理html文本主要工具是正则表达式。不过正则也有局限,比如匹配标签对。网上找到一个匹配标签对的正则,复杂的让人抓狂。因此我写一个匹配标签对的类,它的功能可示例如下:

原文本:"<a><a></a><b><a></a></b><c></c></a>"

对标签a进行匹配后:"<a1><a2></a-2><b><a3></a-3></b><c></c></a-1>"

package office;

import java.util.List;

import tools.EasyRegex;
/*
 *  配对原理:一对标签之间嵌套的子标签,其开始标志数量和结束标志数量相等
 */

/**
 * 配对text文本中查找到的第一对tag标签,开始标志加id,结束标志加-id
 * 比如把<a></a> 标识为<a1></a-1>
 * @author IBM
 */
public class TagPair {
	int id = 0;
	String tag;
	public String result = "";
	
	/**
	 * @param text
	 * @param tag 标签名,使用小写
	 * @return
	 */
	public TagPair(String text,String tag,int id)
	{
		this.id = id;
		this.tag = tag;
		
		String re = text;
		
		int e =0;
		int s = 0;
		
		int i = re.indexOf(tag);

		while(i>=0){
			if(re.indexOf("<", i-1) == i-1){
				s++;
				if(s == 1){//indexOf大小写敏感特性这里正好为我所有,将标志过的标签转为大写,这样下次indexOf就不会再把它列入查找结果
					re = re.substring(0, i) + tag.toUpperCase()+ String.valueOf(id) + re.substring(i+tag.length());
				}
			}
			else if(re.indexOf("</", i-2) == i-2){
				e++;
				if(e == s){
					result = re.substring(0, i) + tag.toUpperCase()+ String.valueOf(id*-1) + re.substring(i+tag.length());
					break;
				}
			}
			i = re.indexOf(tag,i+tag.length());
		}
	}
	
	/**
	 * tag使用小写
	 * @param text
	 * @param tag
	 * @return
	 */
	public static String pair(String text,String tag)
	{
		//String re = toLowercase(text);//如果能保证标签都是小写形式可省略此步骤
		String re = text;
		int id = 1;
		TagPair tp = new TagPair(re,tag,id);
		
		while(tp.result.length() > 0){
			re = tp.result;
			tp = new TagPair(tp.result,tag,++id);
		}
		return re;
	}
	
	/**
	 * 大小写不敏感
	 * @param html
	 * @return
	 */
	public static String unPair(String html)
	{
		String re = html.replaceAll("(</?[a-gA-Gi-zI-Z]{1,8})(-?\\d{1,5})([^>]*?>)", "$1$3");
		return re;
	}

	public static String toLowercase(String html)
	{
		String re = html;
		EasyRegex reg = new EasyRegex("<[^>]+?>");
		List<String> ms = reg.matchs(re);
		for(String t : ms){
			re = re.replace(t, t.toLowerCase());
		}
		return re;
	}
}

OpenOffice (版本4)+ jodconverter(版本3)转换代码:

package office;
import java.io.File;
import java.util.List;

import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;

import tools.EasyFile;
import tools.EasyRegex;

public class Office2html {

	/**
	 * 把office文件转换成html
	 * @param file office文件完整路径
	 * @param folder html文件及其包含资源存放路径
	 * @return 返回html纯文本内容
	 */
	public static String convert(String file)
	{
		OfficeManager officeManager = null;
		try{
			EasyFile f = new EasyFile(file);//这是我的一个工具类,对File进行了一下再包装,可用File类代替
			
			if(f.isExists()){
				String output = f.getFolder() +"/"+f.nameWithoutExt() +".html";
				
				DefaultOfficeManagerConfiguration config = new DefaultOfficeManagerConfiguration();

		        config.setOfficeHome("C:\\Program Files\\OpenOffice 4");
		        officeManager = config.buildOfficeManager();
		        officeManager.start();
		        
				
		        OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
		        File outputFile = new File(output);

		        converter.convert(f.getFile(), outputFile);//转换
		        
		        String temp = EasyFile.readAllText(output, "GBK");
		        EasyFile.writeAllText(output, clearFormat(f.fileExt(),temp));
			}
			
	        return "";
		}
		catch(Exception e){
			e.printStackTrace();
			return "";
		}
		finally{
           if (officeManager != null) {
                officeManager.stop(); 
            }
		}
	}
	
	/**
	 * ext表示转换前文件类型扩展名
	 * @param ext
	 * @param html
	 * @return
	 */
	static String clearFormat(String ext,String html)
	{
		String content = html;
		try{
	        if(ext.equals("doc") || ext.equals("docx")){
				//去除多余span标签
				content = content.replaceAll("</?SPAN[^>]*?>", "");  
				content = content.replaceAll("<META[^>]+?charset=[^>]+?>", //设定网页编码
						"<HEAD>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />");  
                                //设置内容宽度并居中(接近A4纸宽度)
				content = content.replaceAll("<BODY[^>]*?>", "$0\n<div style=\"width:800px;margin:0 auto;\">");  
				content = content.replaceAll("</BODY>", "</div>\n</BODY>");  
				content = content.replaceFirst("<BODY", "<BODY style=\"text-align:center;\" ");
				//让图片者水平居中
				content = content.replaceAll("<IMG([^>]+)ALIGN=[A-Z]{3,6}", "<IMG$1");  
				content = content.replaceAll("<IMG[^>]+?>", "<div align=\"center\">$0</div>");   
				//下面是找出所有带align属性的p标签,改为div(对齐属性在P标签里无效果)。不能把P全变成div,那样失真严重。

				content = TagPair.toLowercase(content);
				content = TagPair.pair(content, "p");
				
				EasyRegex reg = new EasyRegex("(?<=<p)\\d{1,5}(?=.+align=)",true);
				List<String> ls = reg.matchs(content);
				for(String s : ls){
					content = content.replaceFirst("<P"+s, "<div");
					content = content.replaceFirst("</P-"+s, "</div");
				}
				
				content = TagPair.unPair(content);
				content = content.replaceAll("line-height: 100%", ""); //这个属性败事有余,取消掉  
	        }
	        else{
	        	EasyRegex reg = new EasyRegex("<META[^>]+?charset=[^>]+?>");
	        	content = content.replaceFirst(reg.match(content),
	        			"<HEAD>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />");
	        	//excel中不设边框依然有浅灰色线,但生成html就啥也没有显得太苍白,所以刻意加上。
	        	if(content.indexOf("border-top:") < 0 && content.indexOf("border-left:")<0){
		        	reg = new EasyRegex("<TABLE[^>]+?>");
		        	content = content.replaceFirst(reg.match(content),//
		        			"<TABLE border=\"1\" bordercolor=\"#a0c6e5\" style=\"border-collapse:collapse;\">");
	        	}
	        }

		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	    return content;  
	}
}

注:word中的图片会被放到和html同位置文件夹下

经过这一番处理,生成的html文件凑和着能看了。但毕竟word和浏览器是不同的软件,对代码的解析有很多不一样地方。比如有的文本在word中显示居中,生成html就没这个效果了。这不是java转换的问题,是因为那段文本其实本就没有居中属性,word只是根据其上下文环境,把它给居中显示了,但浏览器显然没这样功能。

至于表格,由于其本身格式就比较固定,所以在html下表现出来和excel中差别不大。不过我也发现了一个bug,就是在转换一个较大的excel文件时,本来某单元格中只有一句话,结果转换出来后,此格中这句话重复了数十遍,这应该是openoffice或jodconverter的bug。


欢迎大家一起探讨、进步!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值