您的位置:首页 > 编程语言 > Java开发

Java操作word模板文件

2011-07-01 11:14 246 查看
关于导出word文档,之前想过用ireport但模板文件比较复杂不容易画。所以采取了Java操作word文件,替换word中的元素方法

模板文件如下

单位名称:XXXX科技股份有限司                            NO: 000000000000000000001


类代码:

/**
* OperatorRTFCN.java
* 版权所有(C) 2011 cuiran2001@163.com
* 创建:崔冉 2011-6-30 上午09:29:32
*/

package com.cayden.jsfdemo.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;

/**
* @author 崔冉
* @version 1.0.0
* @desc
*/
public class OperatorRTFCN {
/**
* 字符串转换为rtf编码
* 2009-7-5 wde 增加中文支持
* @param content
* @return
*/
int inext=0;//用来判断中文 编码出现 第一次出现为0 第二次出现为1 add by wde
public String strToRtf(String content){
char[] digital = "0123456789ABCDEF".toCharArray();
StringBuffer sb = new StringBuffer("");
byte[] bs = content.getBytes();
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
/*2009-7-5 add by wde 增加中文支持
*思路:通过getBytes获取的中文的assii小于0,根据rtf中文的的编码
* 所以只需要在中文的2个编码 第一个编码前加 第二个编码后加
* 加了一个变量inext 用来判断中文的assii 前一个和后一个。
* 这样在rtf中文的乱码就可以解决了。
*/
if(bs[i]>0){
sb.append("//'");
}else{
if(inext==0){
//通过写字板创建的rtf模板 add by wde
//sb.append("//lang2052//f1");
//通过WPS2009创建的rtf模板 add by wde
// sb.append("//lang1033 //langnp1033 //langfe2052 //langfenp2052 //cf1");
//通过MS word创建的rtf模板 add by wde
sb.append("//loch//af2//hich//af2//dbch//f31505");
sb.append("//'");
inext=1;
}else{
sb.append("//'");
}
}
sb.append(digital[bit]);
bit = bs[i] & 0x0f;
sb.append(digital[bit]);
if(bs[i]<0&&inext==1){
// 通过写字板创建的rtf模板 add by wde
//sb.append("//lang1033//f0");
// 通过WPS2009创建的rtf模板 add by wde
//sb.append(" //lang1033//langnp1033 //langfe2052//langfenp2052 //cf1");
// 通过MS word创建的rtf模板 add by wde
sb.append("//hich//af2//dbch//af31505//loch//f2");
inext=0;
}
}

return sb.toString();
}

/**
* 替换文档的可变部分 add by wde 2009-7-6
* @param content 原来的文本
* @param markersign 标记符号
* @param replacecontent 替换的内容
* 用replacecontent替换markersign
* @return
*/
public String replaceRTF(String content,String markersign,String replacecontent){
String rc = strToRtf(replacecontent);
String target = "";
markersign="$"+markersign+"$";
target = content.replace(markersign,rc);
return target;
}

/*替换模板 add by wde 2009-7-6
* @param inputPath
* @param outPath
* @param data
* @return
*/
public void rgModel(String inputPath, String outPath, HashMap data) {
// TODO Auto-generated method stub
/* 字节形式读取模板文件内容,将结果转为字符串 */
String sourname = inputPath+"//"+"模板ZH.rtf";
String sourcecontent = "";
InputStream ins = null;
try{
ins = new FileInputStream(sourname);
//byte[] b = new byte[1024];//对应在while中使用bytesRead = ins.read(b, 0, 1024);
//byte[] b = new byte[16384]; //对应在while中使用bytesRead = ins.read(b);
byte[] b = new byte[1638400];//提高对于RTF文件的读取速度,特别是对于1M以上的文件 if (ins == null) {

int bytesRead = 0;
while (true) {
//bytesRead = ins.read(b, 0, 1024); // return final read bytes counts
bytesRead = ins.read(b,0,1638400);
if(bytesRead == -1) {// end of InputStream
System.out.println("读取模板文件结束");
break;
}
sourcecontent += new String(b, 0, bytesRead); // convert to string using bytes
}
}catch(Exception e){
e.printStackTrace();
}
/* 修改变化部分 */
String targetcontent = "";
String oldText="";
Object newValue;
/* 结果输出保存到文件 */
try {
Iterator keys = data.keySet().iterator();
int keysfirst=0;
while (keys.hasNext())
{
oldText = (String) keys.next();
newValue = data.get(oldText);
String newText = (String) newValue;
inext=0;//add by wde 改为初始状态
if(keysfirst==0){
targetcontent = replaceRTF(sourcecontent,oldText,newText);
keysfirst=1;
}else{
targetcontent = replaceRTF(targetcontent,oldText,newText);
keysfirst=1;
}
}

FileWriter fw = new FileWriter(outPath,true);
PrintWriter out = new PrintWriter(fw);
if(targetcontent.equals("")||targetcontent==""){
out.println(sourcecontent);
}else{
out.println(targetcontent);
}
out.close();
fw.close();
System.out.println(outPath+" 生成文件成功");
} catch (IOException e) {

e.printStackTrace();
}
}

public static void main(String[] args) {

SimpleDateFormat sdf=new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date current=new Date();
String targetname = sdf.format(current).substring(0,4) + "年";
targetname += sdf.format(current).substring(5,7) + "月";
targetname += sdf.format(current).substring(8,10) + "日";
targetname += sdf.format(current).substring(11,13) + "时";
targetname += sdf.format(current).substring(14,16) + "分";
targetname += sdf.format(current).substring(17,19) + "秒";
targetname+=".rtf";
OperatorRTFCN oRTF = new OperatorRTFCN();

//*****************************************
//利用HashMap读取数据库中的数据
HashMap map = new HashMap();
// map.put("timetop","张三");
// map.put("info","0155");
// map.put("idea","公元前2000年");
// map.put("advice","13");
// map.put("infosend","168");
map.put("ACCTNAME", "xxx科技股份有限公司");
map.put("SN", "000000000000000000001");

//******************************************
oRTF.rgModel("C://YQ","c://YQ//"+targetname, map);

}

}

代码中对中文也进行了相应处理,值得注意的是:

1.在模板文件写$XX$时候,直接在模板文件写会出现错误。所以我一般是在eclipse中写好复制过去。

2.由于我电脑装了wps所以如果用wps打开的话会乱码,建议用word打开。2003 ,2007,2010都可以。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: