先下载jacob.jar包。解压后将jacob.dll放到windows/system32下面或\jre\bin下面。将jacob.jar加入项目。
这样项目的环境基本上搭建完成,接下来就是书写相关的代码:
/**
* 传入数据为HashMap对象,对象中的Key代表word模板中要替换的字段,Value代表用来替换的值。
* word模板中所有要替换的字段(即HashMap中的Key)以特殊字符开头和结尾,
* 如:$code$、$date$……,以免执行错误的替换。
* 所有要替换为图片的字段,Key中需包含image或者Value为图片的全路径
* (目前只判断文件后缀名为:.bmp、.jpg、.gif)。
* 要替换表格中的数据时,HashMap中的Key格式为“[email protected]”,其中:
* R代表从表格的第R行开始替换,N代表word模板中的第N张表格;
* Value为ArrayList对象,ArrayList中包含的对象统一为String[],一条String[]代表一行数据,
* ArrayList中第一条记录为特殊记录,记录的是表格中要替换的列号,
* 如:要替换第一列、第二列、第三列的数据,则第一条记录为String[3] {"1","2","3"}。
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
/**
* 利用word模板生成word文件
* @typename:Java2word
* @author: FishRoad
* @since: 2015年8月24日 下午2:47:41
*
*/
public class Java2word {
private boolean saveOnExit;
/**
* word文档
*/
Dispatch doc = null;
/**
* word运行程序对象s
*/
private ActiveXComponent word;
/**
* 所有word文档
*/
private Dispatch documents;
/**
* 构造函数
*/
public Java2word() {
if(word==null){
word = new ActiveXComponent("Word.Application");
word.setProperty("Visible",new Variant(false));
}
if(documents==null)
documents = word.getProperty("Documents").toDispatch();
saveOnExit = false;
}
/**
* 设置参数:退出时是否保存
* @param saveOnExit boolean true-退出时保存文件,false-退出时不保存文件
*/
public void setSaveOnExit(boolean saveOnExit) {
this.saveOnExit = saveOnExit;
}
/**
* 得到参数:退出时是否保存
* @return boolean true-退出时保存文件,false-退出时不保存文件
*/
public boolean getSaveOnExit() {
return saveOnExit;
}
/**
* 打开文件
* @param inputDoc String 要打开的文件,全路径
* @return Dispatch 打开的文件
*/
public Dispatch open(String inputDoc) {
return Dispatch.call(documents,"Open",inputDoc).toDispatch();
}
/**
* 选定内容
* @return Dispatch 选定的范围或插入点
*/
public Dispatch select() {
return word.getProperty("Selection").toDispatch();
}
/**
* 把选定内容或插入点向上移动
* @param selection Dispatch 要移动的内容
* @param count int 移动的距离
*/
public void moveUp(Dispatch selection,int count) {
for(int i = 0;i < count;i ++)
Dispatch.call(selection,"MoveUp");
}
/**
* 把选定内容或插入点向下移动
* @param selection Dispatch 要移动的内容
* @param count int 移动的距离
*/
public void moveDown(Dispatch selection,int count) {
for(int i = 0;i < count;i ++)
Dispatch.call(selection,"MoveDown");
}
/**
* 把选定内容或插入点向左移动
* @param selection Dispatch 要移动的内容
* @param count int 移动的距离
*/
public void moveLeft(Dispatch selection,int count) {
for(int i = 0;i < count;i ++) {
Dispatch.call(selection,"MoveLeft");
}
}
/**
* 把选定内容或插入点向右移动
* @param selection Dispatch 要移动的内容
* @param count int 移动的距离
*/
public void moveRight(Dispatch selection,int count) {
for(int i = 0;i < count;i ++)
Dispatch.call(selection,"MoveRight");
}
/**
* 把插入点移动到文件首位置
* @param selection Dispatch 插入点
*/
public void moveStart(Dispatch selection) {
Dispatch.call(selection,"HomeKey",new Variant(6));
}
/**
* 从选定内容或插入点开始查找文本
* @param selection Dispatch 选定内容
* @param toFindText String 要查找的文本
* @return boolean true-查找到并选中该文本,false-未查找到文本
*/
public boolean find(Dispatch selection,String toFindText) {
//从selection所在位置开始查询
Dispatch find = word.call(selection,"Find").toDispatch();
//设置要查找的内容
Dispatch.put(find,"Text",toFindText);
//向前查找
Dispatch.put(find,"Forward","True");
//设置格式
Dispatch.put(find,"Format","True");
//大小写匹配
Dispatch.put(find,"MatchCase","True");
//全字匹配
Dispatch.put(find,"MatchWholeWord","True");
//查找并选中
return Dispatch.call(find,"Execute").getBoolean();
}
/**
* 把选定内容替换为设定文本
* @param selection Dispatch 选定内容
* @param newText String 替换为文本
*/
public void replace(Dispatch selection,String newText) {
//设置替换文本
Dispatch.put(selection,"Text",newText);
}
/**
* 全局替换
* @param selection Dispatch 选定内容或起始插入点
* @param oldText String 要替换的文本
* @param newText String 替换为文本
*/
public void replaceAll(Dispatch selection,String oldText,Object replaceObj) {
//移动到文件开头
moveStart(selection);
if(oldText.startsWith("table") || replaceObj instanceof ArrayList)
replaceTable(selection,oldText,(ArrayList) replaceObj);
else {
String newText = (String) replaceObj;
if(newText==null)
newText="";
if(oldText.indexOf("image") != -1&!newText.trim().equals("") || newText.lastIndexOf(".bmp") != -1 || newText.lastIndexOf(".jpg") != -1 || newText.lastIndexOf(".gif") != -1){
while(find(selection,oldText)) {
replaceImage(selection,newText);
Dispatch.call(selection,"MoveRight");
}
}else{
while(find(selection,oldText)) {
replace(selection,newText);
Dispatch.call(selection,"MoveRight");
}
}
}
}
/**
* 替换图片
* @param selection Dispatch 图片的插入点
* @param imagePath String 图片文件(全路径)
*/
public void replaceImage(Dispatch selection,String imagePath) {
Dispatch.call(Dispatch.get(selection,"InLineShapes").toDispatch(),"AddPicture",imagePath);
}
/**
* 替换表格
* @param selection Dispatch 插入点
* @param tableName String 表格名称,
* 形如[email protected]、[email protected][email protected],R代表从表格中的第N行开始填充,N代表word文件中的第N张表
* @param fields HashMap 表格中要替换的字段与数据的对应表
*/
public void replaceTable(Dispatch selection,String tableName,ArrayList dataList) {
if(dataList.size() <= 1) {
System.out.println("Empty table!");
return;
}
//要填充的列
String[] cols = (String[]) dataList.get(0);
//表格序号
String tbIndex = tableName.substring(tableName.lastIndexOf("@") + 1);
//从第几行开始填充
int fromRow = Integer.parseInt(tableName.substring(tableName.lastIndexOf("$") + 1,tableName.lastIndexOf("@")));
//所有表格
Dispatch tables = Dispatch.get(doc,"Tables").toDispatch();
//要填充的表格
Dispatch table = Dispatch.call(tables,"Item",new Variant(tbIndex)).toDispatch();
//表格的所有行
Dispatch rows = Dispatch.get(table,"Rows").toDispatch();
//填充表格
for(int i = 1;i < dataList.size();i ++) {
//某一行数据
String[] datas = (String[]) dataList.get(i);
//在表格中添加一行
if(Dispatch.get(rows,"Count").getInt() < fromRow + i - 1)
Dispatch.call(rows,"Add");
//填充该行的相关列
for(int j = 0;j < datas.length;j ++) {
//得到单元格
Dispatch cell = Dispatch.call(table,"Cell",Integer.toString(fromRow + i - 1),cols[j]).toDispatch();
//选中单元格
Dispatch.call(cell,"Select");
//设置格式
Dispatch font = Dispatch.get(selection,"Font").toDispatch();
Dispatch.put(font,"Bold","0");
Dispatch.put(font,"Italic","0");
//输入数据
Dispatch.put(selection,"Text",datas[j]);
}
}
}
/**
* 保存文件
* @param outputPath String 输出文件(包含路径)
*/
public void save(String outputPath) {
Dispatch.call(Dispatch.call(word,"WordBasic").getDispatch(),"FileSaveAs",outputPath);
}
/**
* 关闭文件
* @param document Dispatch 要关闭的文件
*/
public void close(Dispatch doc) {
Dispatch.call(doc,"Close",new Variant(saveOnExit));
word.invoke("Quit",new Variant[]{});
word = null;
}
/**
* 根据模板、数据生成word文件
* @param inputPath String 模板文件(包含路径)
* @param outPath String 输出文件(包含路径)
* @param data HashMap 数据包(包含要填充的字段、对应的数据)
*/
public void toWord(String inputPath,String outPath,HashMap data) {
String oldText;
Object newValue;
try {
if(doc==null)
doc = open(inputPath);
Dispatch selection = select();
Iterator keys = data.keySet().iterator();
while(keys.hasNext()) {
oldText = (String) keys.next();
newValue = data.get(oldText);
replaceAll(selection,oldText,newValue);
}
save(outPath);
} catch(Exception e) {
System.out.println("操作word文件失败!");
e.printStackTrace();
} finally {
if(doc != null)
close(doc);
}
}
public synchronized static void word(String inputPath,String outPath,HashMap data){
Java2word j2w = new Java2word();
j2w.toWord(inputPath,outPath,data);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
//替换word中相关的字段
HashMap data = new HashMap();
data.put("$reportDept$","2007-8-1");
data.put("$findDate$","2007-8-2");
data.put("$finder$","kdl");
data.put("$lineName$","5号线");
data.put("$voltageRate$","11月13日");
data.put("$towerNumberBound$","2004年11月10日");
data.put("$image1$","C:\\Users\\Administrator\\Pictures\\1.jpg");
data.put("$name$", "FishRoad");
data.put("$age$", "24");
//替换word中表格的数据
/**
* 要替换表格中的数据时,HashMap中的Key格式为“[email protected]”,其中:
* R代表从表格的第R行开始替换,N代表word模板中的第N张表格;
* Value为ArrayList对象,ArrayList中包含的对象统一为String[],
* 一条String[]代表一行数据,ArrayList中第一条记录为特殊记录,记录的是表格中要替换的列号,
* 如:要替换第一列、第二列、第三列的数据,则第一条记录为String[3] {"1","2","3"}
*/
ArrayList table1 = new ArrayList(3);
String[] fieldName1 = {"1","2","3"};
table1.add(fieldName1);
String[] field11 = {"1","751002","华夏证券"};
table1.add(field11);
String[] field21 = {"2","751004","国泰君安"};
table1.add(field21);
String[] field31 = {"3","751005","海通证券"};
table1.add(field31);
data.put("[email protected]",table1);
Java2word j2w = new Java2word();
long time1 = System.currentTimeMillis();
j2w.toWord("E:/template.doc","E:/result.doc",data);
System.out.println("time cost : " + (System.currentTimeMillis() - time1));
}
}
以上是相关的代码,接下来就要配置word模板,如下:
导出的结果如下图:
对抗生成网络GAN(优化目标篇)
延迟队列:根据上面的方案我门知道我们生产中不可缺少的使用延迟队列,我们如何实现今天介绍下需要安装插件https://www.rabbitmq.com/community-plugins.html 这个里面有rabbitmq的插件集合我们从中找到rabbitmq_delayed_message_exchange 点击下载,下载后的代码放到你的安装目录下面的plugins目录下比如我放的就是:/usr/local/Cellar/rabbitmq/3.8.16/plugins 这个目录下面,找自己的
由于业务需要展示世界地图,并且对地图数据进行操作;前期选用native-echarts,但是该组件有三个问题:1.长期不维护;2.echarts版本较老;3.没有自带的地图功能;故有了该组件的诞生,废话不多说,上手:一、...
目前手机短信息的应用越来越广泛,互联网上提供短信息发送的站点也越来越多,但一些站点的服务并不尽如人意,往往发出去的短信息石沉大海。最可靠的发送方法当然是用手中的手机了,如果设置了状态报告,更能确切知道对方是否收到了此条信息。手机发送尽管比较可靠, 但也存在输入麻烦、效率低的问题。本文介绍一种方法,只要手机能够与电脑相连(通过红外端口或用手机数据线连接串行口,同时手机支持GSM AT指令集),就可以...
Python中 partition() 函数的作用是在首次出现分隔字符串的位置把字符串分割为三部分,并以元组的形式返回分割结果,返回的元组中包括分隔字符串之前的部分,分隔字符串本身及分隔字符串之后的部分。一、partition()函数的语法格式string_name.partition(separator)(1)string_name 为要被分隔的字符串或字符串变量。(2)该函数有一个字符串类型的...
深入分析 Java 中的中文编码问题几种常见的编码格式为什么要编码不知道大家有没有想过一个问题,那就是为什么要编码?我们能不能不编码?要回答这个问题必须要回到计算机是如何表示我们人类能够理解的符号的,这些符号也就是我们人类使用的语言。由于人类的语言有太多,因而表示这些语言的符号太多,无法用计算机中一个基本的存储单元—— byte 来表示,因而必须要经过...
调试在64位Debian上编译好的Linux 0.11(一)本机环境:SMP Debian 3.11.6-1 (2013-10-27) x86_64 GNU/Linuxgcc (Debian 4.8.2-5) 4.8.2GNU assembler (GNU Binutils for Debian) 2.23.90.20131116GNU ld (GNU Binutils for Debian) 2...
黑客技术点击右侧关注,了解黑客的世界!Linux编程点击右侧关注,免费入门到精通!回想一下我们发布 iOS 应用,不仅步骤繁琐,非常耗时。一旦其中一步失误了,又得重新来。...
我用2003的IIS做了个虚拟目录,可以在浏览器上列出文件,但ISO,JNLP等的文件不能下载,在下载时提示文件不存在,但服务器上是有此文件的,其他的可以下载。解决方式是:在设置该虚拟目录的属性->HTTP头->MIME类型,把ISO,JNLP等扩展名加进去就可以了。应为IIS不认这些扩展名,所以提示文件不存在,把扩展名加进去就ok了。 转载...
【赛迪网报道】Linux系统下真正有危害的是内存泄漏的堆积,这会最终消耗尽系统任何的内存。下面是排查和解决方案与大家一起分享。1、Linux 内存监控内存泄漏的定义:一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程式从堆中分配的,大小任意的(内存块的大小能够在程式运行期决定),使用完后必须显示释放的内存。应用程式一般使用malloc,realloc,new等函数从堆中分配到一块内存,使用完后,...
基于51单片机的直流数字电压表(0-5V)利用串行A/D转换器TLC549对输入信号电压源进行采集转换成数字信号给51单片机,经单片机进行数据处理后给1602液晶显示。误差小于1%.#include#include#define uint unsigned int#define uchar unsigned charuchar LCD[6]; //电
承接上文,发现在使用Python C/C++ API扩展Python模块时,总要在各种各样的地方考虑到引用计数问题,稍不留神可能会导致扩展的模块存在内存泄漏。引用计数问题是C语言扩展Python模块最头疼的地方,需要由程序员对使用的每个C API都要充分了解,甚至要熟悉源码才能精确掌握什么时候引用计数加一,什么时候减一。本文为翻译文章,我觉得对于源码中的引用计数讲解得比较清楚,所以就翻译为中文。h...