读取word文件,字体,颜色

在Android读取Word文件时,在网上查看时可以用tm-extractors,但好像没有提到怎么读取Word文档中字体的颜色,字体,上下标等相关的属性。但由于需要,要把doc文档中的内容(字体,下划线,颜色等)读取应用到android中(不包括图片和图表)。

后面采用的是poi三方jar包(原包太大,可以从源代码里自己抽取有用的一些代码减少包的大小)。

我的想法是:把doc中的内容解析出来后,加上html对应的标签,在android中通过Html.fromHtml在TextView中进行显示,或者通过WebView.loadData进行加载显示

但测试后,发现如果加载太多内容的话,在Android中效率不行。

 

效果(该图的效果是在TextView中的效果,在WebView中效果会更好些):

doc图:

 

 

android图:

 

 

做法1:(解析为span样式的,这种做法只能用WebView方式加载,Html.fromHtml无效)

/**Span样式
	 * 通过字体的样式进行加载
	 * @param inputStream
	 * @return
	 */
	public static String readDocToSpanByRun(InputStream inputStream) {
		HWPFDocument hwpfDocument = null;
		if(inputStream == null)
			throw new RuntimeException("inputStream is null ...");
		try{
			hwpfDocument = new HWPFDocument(inputStream);
		}catch(Exception e) {
			throw new RuntimeException("HWPFDocment Exception", e);
		}
		Range allRange = hwpfDocument.getRange();
		int length = allRange.numCharacterRuns();
		StringBuffer sb = new StringBuffer();
		CharacterRun cur;
		String text = "";
		for (int i = 0; i < length; i++) {
			cur = allRange.getCharacterRun(i);
			sb.append(CharacterRunUtils.toSpanType(cur));
			text = CharacterRunUtils.getSpicalSysbomByRun(cur.text());
			if(cur.getSubSuperScriptIndex() == 1)
				sb.append("<sup>").append(text).append("</sup>");
			else if(cur.getSubSuperScriptIndex() == 2) 
				sb.append("<sub>").append(text).append("</sub>");
			else 
				sb.append(text);
			sb.append("</span>");
		}
		return sb.toString();
	}
	

 

做法2:(解析为font样式的,Html.fromHtml有效,但对应size的设置无效果)

 

/**
	 * Html样式
	 * 通过字体样式解析
	 * @param inputStream
	 * @return
	 */
	public static String readDocToHtml(InputStream inputStream) {
		HWPFDocument hwpfDocument = null;
		if(inputStream == null)
			throw new RuntimeException("inputStream is null ...");
		try{
			hwpfDocument = new HWPFDocument(inputStream);
		}catch(Exception e) {
			throw new RuntimeException("HWPFDocment Exception", e);
		}
		CharacterRun  cur = null;
		StringBuffer sb = new StringBuffer();
		StringBuffer charStr =  new StringBuffer();
		Range allRange = hwpfDocument.getRange();
		for(int i = 0; i < allRange.numCharacterRuns(); i++) {
			cur = allRange.getCharacterRun(i);
			sb.append(CharacterRunUtils.fontFaceColorSizeToHtml(cur));
			charStr.append(CharacterRunUtils.toSupOrSub(cur, CharacterRunUtils.getSpicalSysbomByRun(cur.text())));
			if(cur.isBold())  {
				charStr.insert(0, "<b>");
				charStr.insert(charStr.length(), "</b>");
			}
			if(cur.getUnderlineCode() != 0) { 
				charStr.insert(0, "<u>");
				charStr.insert(charStr.length(), "</u>");
			}
			if(cur.isItalic()) {
				charStr.insert(0, "<i>");
				charStr.insert(charStr.length(), "</i>");
			}
			if(cur.isStrikeThrough()) {
				charStr.insert(0, "<s>");
				charStr.insert(charStr.length(), "</s>");
			}
			sb.append(charStr).append("</font>");
			charStr.setLength(0);
		}
		hwpfDocument = null;
		return sb.toString();
	}
 

 以下是会用到的方法:

 

/**
 *处理字体相关的属性 
 */
public class CharacterRunUtils {

	private static final short ENTER_ASCII = 13;
	private static final short SPACE_ASCII = 32;
	private static final short TABULATION_ASCII = 9;

	/**
	 * 比对字体是否相同
	 * 可以继续加其它属性
	 * @param cr1
	 * @param cr2
	 * @return
	 */
	public static boolean compareCharStyleForSpan(CharacterRun cr1,
			CharacterRun cr2) {
		return cr1.isBold() == cr2.isBold()
				&& cr1.getFontName().equals(cr2.getFontName())
				&& cr1.getFontSize() == cr2.getFontSize()
				&& cr1.isItalic() == cr2.isItalic()
				&& cr1.getColor() == cr2.getColor()
				&& cr1.getUnderlineCode() == cr2.getUnderlineCode()
				&& cr1.isStrikeThrough() == cr2.isStrikeThrough()
				&& cr1.getColor() == cr2.getColor();
	}

	public static boolean compareCharColor(CharacterRun cr1, CharacterRun cr2) {
		return cr1.getFontName().equals(cr2.getFontName())
				&& cr1.getFontSize() == cr2.getFontSize()
				&& cr1.getColor() == cr2.getColor();
	}

	public static String getSpicalSysbom(char currentChar) {
		String tempStr = "";
		if (currentChar == ENTER_ASCII) {
			tempStr += "<br/>";
		} else if (currentChar == SPACE_ASCII) {
			tempStr += "&nbsp;";
		} else if (currentChar == TABULATION_ASCII) {
			tempStr += "&nbsp;&nbsp;&nbsp;";
		} else {
			tempStr += currentChar;
		}
		return tempStr;
	}
	
	public static String getSpicalSysbomSpan(char currentChar) {
		String tempStr = "";
		if (currentChar == ENTER_ASCII) {
			tempStr += "<br/>";
		} else if (currentChar == SPACE_ASCII) {
			tempStr += "&nbsp;";
		} else if (currentChar == TABULATION_ASCII) {
			tempStr += "&nbsp;&nbsp;&nbsp;";
		}
		return tempStr;
	}

	/**
	 * 特殊字符的取代
	 * @param currentChar
	 * @return
	 */
	public static String getSpicalSysbomByRun(String currentChar) {
		StringBuffer tempStr = new StringBuffer();
		int length = currentChar.length();
		for (int i = 0; i < length; i++) {
			tempStr.append(getSpicalSysbom(currentChar.charAt(i)));
		}
		return tempStr.toString();
	}

	/**
	 * span方式前缀
	 * @param cr
	 * @return
	 */
	public static String toSpanType(CharacterRun cr) {
		StringBuffer spanStyle = new StringBuffer("<span style='font-family:");
		spanStyle.append(cr.getFontName()).append("; font-size:")
				.append(cr.getFontSize() / 2).append("pt;");
		if (cr.isBold())
			spanStyle.append("font-weight:bold;");
		if (cr.isItalic())
			spanStyle.append("font-style:italic;");
		if (cr.isStrikeThrough())
			spanStyle.append("text-decoration:line-through;");
		if (cr.getUnderlineCode() != 0)
			spanStyle.append("text-decoration:underline;");
		spanStyle.append("color:")
				.append(ColorUtils.getHexColor(cr.getIco24())).append(";")
				.append("'>");
		return spanStyle.toString();
	}

	/**
	 * 为font方式提供<font前缀
	 * @param cr
	 * @return
	 */
	public static String fontFaceColorSizeToHtml(CharacterRun cr) {
		StringBuffer htmlType = new StringBuffer("<font ");
		htmlType.append("size='").append(cr.getFontSize() / 2).append("' ")
				.append("face='").append(cr.getFontName()).append("' ")
				.append("color='")
				.append(ColorUtils.getHexColor(cr.getIco24())).append("'>");
		return htmlType.toString();
	}

	/**
	 * 处理上下标
	 * @param cr
	 * @param currentChar
	 * @return
	 */
	public static String toSupOrSub(CharacterRun cr, String currentChar) {
		int sub = cr.getSubSuperScriptIndex();
		if (sub != 0) {
			if (sub == 1)
				// 上标
				return "<sup>" + currentChar + "</sup>";
			else
				// 下标
				return "<sub>" + currentChar + "</sub>";
		} else
			return currentChar;
	}

	public static String toSupOrSub(CharacterRun cr, char currentChar) {
		return toSupOrSub(cr, new String(new char[]{currentChar}));
	}
}

 

用到的颜色的转换(进行简单的颜色转换)

public class ColorUtils {

	public static int  red(int c) {
		return c & 0XFF;
	}
	
	public static int green(int c) {
		return (c >> 8) & 0XFF;
	}
	
	public static int blue(int c) {
		return (c >> 16) & 0XFF;
	}
	
	public static int rgb(int c) {
		return (red(c) << 16) | (green(c) <<8) | blue(c);
	}

	public static String rgbToSix(String rgb) {
		int length = 6 - rgb.length();
		String str = "";
		while(length > 0){
			str += "0";
			length--;
		}
		return str + rgb;
	}
	
	public static String getHexColor(int color) {
		color = color == -1 ? 0 : color;
		int rgb = rgb(color);
		return "#" + rgbToSix(Integer.toHexString(rgb));
	}
}
 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值