java根据模板修改内容后,生成word,修改后内容中文乱码
Java code
package com.sunyard.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.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class OperatorRTF {
/**
* 字符串转换为rtf编码
*
* @param content
* @return
*/
public String strToRtf(String content) {
try {
System.out.println(content);
content=new String(content.getBytes(),"GB2312");
System.out.println(content);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
char[] digital = "0123456789ABCDEF".toCharArray();
StringBuffer sb = new StringBuffer("");
byte[] bs = null;
bs = content.getBytes();
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append("\\'");
sb.append(digital[bit]);
bit = bs[i] & 0x0f;
sb.append(digital[bit]);
}
return sb.toString();
}
/**
* 替换文档的可变部分
*
* @param content
* @param replacecontent
* @param flag
* @return
*/
public String replaceRTF(String content, String replacecontent, int flag) {
String rc = strToRtf(replacecontent);
String target = "";
System.out.println(rc);
if (flag == 0) {
target = content.replace("$timetop$", rc);
}
if (flag == 1) {
target = content.replace("$info$", rc);
}
if (flag == 2) {
target = content.replace("$idea$", rc);
}
if (flag == 3) {
target = content.replace("$advice$", rc);
}
if (flag == 4) {
target = content.replace("$infosend$", rc);
}
return target;
}
/**
* 获取文件路径
*
* @param flag
* @return
*/
public String getSavePath() {
String path = "D:\\";
File fDirecotry = new File(path);
if (!fDirecotry.exists()) {
fDirecotry.mkdirs();
}
return path;
}
/**
* 半角转为全角
*/
public String ToSBC(String input) {
char[] c = input.toCharArray();
for (int i = 0; i < c.length; i++) {
if (c[i] == 32) {
c[i] = (char) 12288;
continue;
}
if (c[i] < 127) {
c[i] = (char) (c[i] + 65248);
}
}
return new String(c);
}
public void rgModel(String username, String content) {
/* 构建生成文件名 targetname:12时10分23秒_username_记录.rtf */
Date current = new Date();
SimpleDateFormat sdf = new java.text.SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
String targetname = sdf.format(current).substring(11, 13) + "时";
targetname += sdf.format(current).substring(14, 16) + "分";
targetname += sdf.format(current).substring(17, 19) + "秒";
targetname += "_" + username + "_记录.doc";
/* 字节形式读取模板文件内容,将结果转为字符串 */
String strpath = getSavePath();
String sourname = strpath + "\\" + "档案利用登记单.rtf";
String sourcecontent = "";
InputStream ins = null;
try {
ins = new FileInputStream(sourname);
byte[] b = new byte[1024];
if (ins == null) {
System.out.println("源模板文件不存在");
}
int bytesRead = 0;
while (true) {
bytesRead = ins.read(b, 0, 1024); // return final read bytes
// counts
if (bytesRead == -1) {// end of InputStream
System.out.println("读取模板文件结束");
break;
}
// convert to string using bytes
sourcecontent += new String(b, 0, bytesRead);
}
} catch (Exception e) {
e.printStackTrace();
}
/* 修改变化部分 */
String targetcontent = "";
/**
* 拆分之后的数组元素与模板中的标识符对应关系 array[0]:timetop array[1]:info array[2]:idea
* array[3]:advice array[4]:infosend
*/
String array[] = content.split("~");
// 2008年11月27日:更新模板之后时间无需自动填充
for (int i = 0; i < array.length; i++) {
if (i == 0) {
targetcontent = replaceRTF(sourcecontent, array[i], i);
} else {
targetcontent = replaceRTF(targetcontent, array[i], i);
}
}
/* 结果输出保存到文件 */
try {
FileWriter fw = new FileWriter(getSavePath() + "\\" + targetname,
true);
PrintWriter out = new PrintWriter(fw);
System.out.println(targetcontent);
if (targetcontent.equals("") || targetcontent == "") {
out.println(sourcecontent);
} else {
out.println(targetcontent);
}
out.close();
fw.close();
System.out.println(getSavePath() + " 该目录下生成文件" + targetname
+ " 成功");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
OperatorRTF oRTF = new OperatorRTF();
// 被替换内容以"~"符号分割,处理的时候将其拆分为数组即可
String content = "2008Y10M12D9H-2008Y10M12D6H~idea~look~我们参照检验药品的方法~we";
oRTF.rgModel("cheney", content);
}
}
上面的代码是我在网上找到的一种java操作word的方法
java读取word文档时,虽然网上介绍了很多插件poi、java2Word、jacob、itext等等,poi无法读取格式(新的API估计行好像还在处于研发阶段,不太稳定,做项目不太敢用);java2Word、jacob容易报错找不到注册,比较诡异,我曾经在不同的机器上试过,操作方法完全一致,有的机器不报错,有的报错,去他们论坛找高人解决也说不出原因,项目部署用它有点玄;itxt好像写很方便但是我查了好久资料没有见到过关于读的好办法。经过一番选择还是折中点采用rtf最好,毕竟rtf是开源格式,不需要借助任何插件,只需基本IO操作外加编码转换即可。rtf格式文件表面看来和doc没啥区别,都可以用word打开,各种格式都可以设定。
----- 实现的功能:读取rtf模板内容(格式和文本内容),替换变化部分,形成新的rtf文档。
----- 实现思路:模板中固定部分手动输入,变化的部分用$info$表示,只需替换$info$即可。
1、采用字节的形式读取rtf模板内容
2、将可变的内容字符串转为rtf编码
3、替换原文中的可变部分,形成新的rtf文档
这是原作者的想法,可我在使用过程中,发现替换内容中(我们参照检验药品的方法)这个中文,是不能显示的,在word里,把它转换成了iso-8859-1的编码了,不能正常显示中文,我都不知道应该在哪设置编码,才能让它正常显示,原word模板中的中文,可以正常显示,应该是在读取word模板的时候,把编码方式也读进去了,现在就是想请教一下前辈们,应该如何后,自己修改的那些中文,也可以正常显示呢
[b]问题补充:[/b]
汗,这里好象自己不能回复,所以我以这种形式回复。
先感谢一楼,二楼的回答,昨天我有事,请假没上班,所以没能及时回复,先道个歉。
先回答1楼的,在写的时候,我设置编码的话,感觉是无效的,不管我怎么设置,都没用。
再回答2楼的,特别说一下,我试了一下,发现生成的word里,那些修改部分的中文的编码形式改变了,只是还是乱码。后来我把unicode,ISO-8859-1,UTF-8,GB2312,GBK,甚至ASCII都试过了, word里都是不同形式的乱码,就是不出现汉字,真闷,我感觉是在
bs = content.getBytes("unicode");
后,系统后来又默认的把这把转成了ISO-8859-1的形式.
可是
bs = content.getBytes("ISO-8859-1");
我这么设置,word里的汉字是?????
真不知道为什么,要是ISO-8859-1,转ISO-8859-1,应该不会改变的哎
希望高手们,能继续解答,谢谢
[b]问题补充:[/b]
汪兆铭,您好,我不知道您一直观注这个问题,我以为要过会才能看到您的回答,所以,现在才刷新了这个页面,不好意思,先道个歉。
现在回到问题中,我照您的意思,
bs = content.getBytes("unicode");
改了一下,然后输入,可是依然不能正常显示中文,是不是,在哪,还需要再转换一次呢?
[b]问题补充:[/b]
mirzlm@126.com
谢谢,不知道与jdk版本或是什么的没有关系
[b]问题补充:[/b]
汪兆铭,您好,我看了一下您发的东西,我发现了问题的所在,竟然是在表格单元格里面的,就替换出来的是乱码,在表格单元格外面的,是可以正常显示的,您可以去试试,把替换的那个,放在表格里,看看,会不会成功,谢谢你的帮助
[b]问题补充:[/b]
谢谢您,给我这么多的帮助,那应该是我的那个rtf模板的问题了,真的很感谢,谢谢,谢谢,再谢谢
strToRtf方法中的这句
bs = content.getBytes();
换成
bs = content.getBytes("unicode");
这句
在读和写的文件流中设置编码看看
新建一个文本文件,输入一些字符,包括英文和中文。
然后用写字板打开。另存为rtf文件。
再用记事本打开这个rtf文件。
可以看到rtf文件实际也是一个文本文件。
头部定义了样式表。
后面是正文。用\pvar标识段落。
中文和oxff以外的字符都用\'xx\'xx标识,其中xxxx是16进制的unicode编码。
你的程序里的
bit = (bs[i] & 0x0f0) >> 4;
sb.append("\'");
sb.append(digital[bit]);
bit = bs[i] & 0x0f;
sb.append(digital[bit]);
就是处理这个编码的。所以这里转byte[]前,要unicode下。
我测试了OperatorRTF 类,
没有乱码
给个邮箱,我发给你。
已发,请查收。
表格里的也没乱码
已发给你了