花了一个下午的时间。磨出来的一个东西..感觉好不错。。拿来分享下。。哈哈。。
大体功能是:根据Excel的内容和Word模板的内容生产Word文档
业务1:excle 有 1000 个人..需要打印出 1000 个人的通知书。(单个的打印、分开管理)
业务2:excle 有 1000 个人..需要连续打印出 1000 个人的通知书。
大体思路:
* 1、定义一个标签格式..本例中是:$(xxx)
* 2、在 word 中编辑好模板样式..另存为html模板。(也可以存为其他格式。但是注意编码问题。不然会乱码)
* 3、读取 excel 中的内容并封住为一个容器: list<map<String,String>>
* 4、读取html模板,并根据标签替换内容。再重新写个文件。
*
开始都一路顺风...后面再连续的分页word文档的时候。遇到麻烦了.开始以为只要在每次循环的地方加上word的分页符就好了。。是的。思路是没错。。问题就出在了怎么加。。。。下面我在唠叨下我的经过:
我一次就是直接读取模板..替换..在循环的地方加上分页代码..结果失败了...效果是word..只看到了excel 第一条记录。开始我还以为是我的代码写错了。。后面在跟踪断点、查看源码才发现..其实循环的没错.....错在每次读模板的时候都有html的头部.等等代码....于是我仔细的查看了单个文件的源码。
当我们把 word 模板另存为 html 的时候。。源码大致分为如下格式:
头部:
<html xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
···································省略
中间:
<body lang=ZH-CN style='tab-interval:21.0pt;text-justify-trim:punctuation'>
<div class=Section1 style='layout-grid:15.6pt'>
<p class=MsoNormal align=center style='text-align:center'><b style='mso-bidi-font-weight:
normal'><span lang=EN-US style='font-size:14.0pt;font-family:黑体'><o:p> </o:p></span></b></p>
·························省略
</div><!-- 我故意把这个 结束的 div 分开..是为了让你们注意到..哈哈..后面还讲到.. --->
底部
</body>
</html>
嘿嘿...经过这么仔细的分析...我估计这下没问题了...于是我把 模板分为 三块...只循环中间的 部分.....满心期待的结果出来。。结果我打开一看 。。。。所有的数据都在一个word里面是...是没错....可是没分页...本来第二页的内容在第一页尾巴上面...
额。。我开始还怀疑是不是 分页代码 写错了。。。我就手动下了一个测试word 另存为html 加上分页代码。在还原回 word ...结果是 分页的....郁闷中.....反复的思考刚才的操作...是不是我的 分页代码放错地方了.....
于是我在测试了下。。这次我把 分页代码 放到了 中部代码的 div 中间。。。O(∩_∩)O哈哈~...结果分页成功..
最后我在模板中插入了一个分页符(是分页符不是回车到第二页啊)
大体思路:
* 1、定义一个标签格式..本例中是:$(xxx)
* 2、在 word 中编辑好模板样式..另存为html模板。但是这里要注意,我们要打开 html 的源码,
* 分解源码为:头部和中间、底部等三部分。(底部模板简单。所以我就写在代码中了),
* 3、读取 excel 中的内容并封住为一个容器: list<map<String,String>>
* 4、读取html头部和中间、底部模板,并根据标签替换中间模板内容。替换完后,在加底部文件。重写文件。生成一个连续的有分页符的word
*
下面的我的代码,附件中我也将上传我的类和文件:
excel操作类:
package cn.xsbiz.main;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
/**
* 业务:java读取Excel
*
*
* @author 妞见妞爱
*
*/
public class OperatorExcel {
/**
* 读取Excel文件的内容
*
* @param file
* 待读取的文件
* @return
*/
public static String readExcel(File file) {
StringBuffer sb = new StringBuffer();
Workbook wb = null;
try {
// 构造Workbook(工作薄)对象
wb = Workbook.getWorkbook(file);
} catch (BiffException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (wb == null)
return null;
// 获得了Workbook对象之后,就可以通过它得到Sheet(工作表)对象了
Sheet[] sheet = wb.getSheets();
if (sheet != null && sheet.length > 0) {
// 对每个工作表进行循环
for (int i = 0; i < sheet.length; i++) {
// 得到当前工作表的行数
int rowNum = sheet[i].getRows();
for (int j = 0; j < rowNum; j++) {
// 得到当前行的所有单元格
Cell[] cells = sheet[i].getRow(j);
if (cells != null && cells.length > 0) {
// 对每个单元格进行循环
for (int k = 0; k < cells.length; k++) {
// 读取当前单元格的值
String cellValue = cells[k].getContents();
sb.append(cellValue + "\t");
}
}
sb.append("\r\n");
}
sb.append("\r\n");
}
}
// 最后关闭资源,释放内存
wb.close();
return sb.toString();
}
/**
*
* 读取 excel 返回 List<Map>
*
* @param file --待读取的文件
* @return
*/
public static List<Map<String, String>> readExcelReList(File file) {
Workbook wb = null;
try {
// 构造Workbook(工作薄)对象
wb = Workbook.getWorkbook(file);
} catch (BiffException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (wb == null)
return null;
// 获得了Workbook对象之后,就可以通过它得到Sheet(工作表)对象了
Sheet[] sheet = wb.getSheets();
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
if (sheet != null && sheet.length > 0) {
// 对每个工作表进行循环
for (int i = 0; i < sheet.length; i++) {
// 得到当前工作表的行数
int rowNum = sheet[i].getRows();
for (int j = 0; j < rowNum; j++) {
// 得到当前行的所有单元格
Cell[] cells = sheet[i].getRow(j);
if (cells != null && cells.length > 0) {
// 因为只需要单元格的部分内容...所以指定读取当前单元格的值
Map<String, String> map = new HashMap<String, String>();
String cellValue = cells[0].getContents().trim();
map.put("town", cellValue);
cellValue = cells[1].getContents().trim();
map.put("village", cellValue);
cellValue = cells[2].getContents().trim();
map.put("name", cellValue);
cellValue = cells[11].getContents().trim();
map.put("tel", cellValue);
cellValue = cells[10].getContents().trim();
map.put("dw", cellValue);
cellValue = cells[12].getContents().trim();
map.put("money", cellValue);
list.add(map);
}
}
}
}
// 最后关闭资源,释放内存
wb.close();
return list;
}
public static void main(String[] args) {
OperatorExcel excel = new OperatorExcel();
File filepath = new File("f://test//test.xls");
String str = excel.readExcel(filepath);
System.out.println(str);
}
}
word操作类:
package cn.xsbiz.main;
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;
import java.util.List;
import java.util.Map;
/**
* 业务:java读取word的模板内容动态生成word
*
* 思路:
* 先用word编辑好模板格式再另存为html;在读取html的内容进行替换。最后保持为word格式
*
* 开始我也另存为word自带的模板老是乱码,,不知道什么原因。。
* 后面改为xml 乱码问题是没了。。但是提示xml内容错误打不开。。
* 最后不得不改为html。测试成功
*
*
* 标签:$(xxx)
*
* @author 妞见妞爱
*
*/
public class OperatorWord {
/**
* 替换文档的可变部分
*
* @param content
* 原来的文本
* @param markersign
* 标记符号
* @param replacecontent
* 替换的内容 用replacecontent替换markersign
* @return
*/
public String replaceModel(String content, String markersign,
String replacecontent) {
String rc = replacecontent;
String target = "";
markersign = "$(" + markersign + ")";
target = content.replace(markersign, rc);
return target;
}
/**
*
* 生产单个的word 文档
*
* @param inputPath --模板的路径
* @param outPath --生成文档的路径
* @param data --传入的数据
*/
public void replaceTemplate(String inputPath, String outPath, Map<String, String> data) {
/* 字节形式读取模板文件内容,将结果转为字符串 */
String sourcecontent = readTemplate(inputPath);
/* 修改变化部分 */
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;
if (keysfirst == 0) {
targetcontent = replaceModel(sourcecontent, oldText, newText);
keysfirst = 1;
} else {
targetcontent = replaceModel(targetcontent, oldText, newText);
keysfirst = 1;
}
}
//System.out.println("=======输出=========");
//System.out.println(targetcontent);
FileWriter fw = new FileWriter(outPath, true);
PrintWriter out = new PrintWriter(fw);
if (targetcontent.equals("")) {
out.println(sourcecontent);
} else {
out.println(targetcontent);
}
out.close();
fw.close();
System.out.println(outPath + " 生成文件成功");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 读取模板的内容
*
* @param inputPath --模板的路径
* @return
*/
public String readTemplate(String inputPath){
/* 字节形式读取模板文件内容,将结果转为字符串 */
String sourname = inputPath;
StringBuffer sourcecontent = new StringBuffer();
InputStream ins = null;
try {
ins = new FileInputStream(sourname);
byte[] b = new byte[2048];// 可以修改[2048]提高对于文件的读取速度;
int bytesRead = 0;
while (true) {
bytesRead = ins.read(b, 0, 2048);
if (bytesRead == -1) {// end of InputStream
break;
}
sourcecontent.append(new String(new String(b, 0, bytesRead).getBytes(), "GBK")); // 转换字符串的 编码格式
}
// sourcecontent = new String(sourcecontent.getBytes(),"UTF-8");
//System.out.println(sourcecontent);
} catch (Exception e) {
e.printStackTrace();
}
return sourcecontent.toString();
}
/**
*
* 生产一个内容连续的 word 文档
*
* @param topPath --模板的头部内容路径
* @param inputPath --模板的主体内容路径
* @param outPath --生成的文件路径
* @param list --传入的数据
*/
public void replaceTemplateAll(String topPath,String inputPath, String outPath, List<Map<String, String>> list) {
/* 字节形式读取模板文件内容,将结果转为字符串 */
String stringTop = readTemplate(topPath);
String stringCenter = readTemplate(inputPath);
StringBuffer targetcontent = new StringBuffer();
targetcontent.append(stringTop);
/* 修改变化部分 */
String tempcontent = "";
String oldText = "";
Object newValue;
/* 结果输出保存到文件 */
try {
//日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy 年 MM 月 dd 日");
String date = sdf.format(new Date());
for(int i=0;i<list.size();i++){
Map<String, String> data = list.get(i);
data.put("date", date);
Iterator keys = data.keySet().iterator();
int keysfirst = 0;
while (keys.hasNext()) {
oldText = (String) keys.next();
newValue = data.get(oldText);
String newText = (String) newValue;
if (keysfirst == 0) {
tempcontent = replaceModel(stringCenter, oldText, newText);
keysfirst = 1;
} else {
tempcontent = replaceModel(tempcontent, oldText, newText);
keysfirst = 1;
}
}
targetcontent.append(tempcontent);
}
//模板的尾部
targetcontent.append("</div></body></html>");
//System.out.println("=======输出=========");
//System.out.println(targetcontent.toString());
FileWriter fw = new FileWriter(outPath, true);
PrintWriter out = new PrintWriter(fw);
if (targetcontent.length() == 0) {
out.println("没有内容!");
} 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("yyyyMMddHHmmss");
Date current = new Date();
String targetname = sdf.format(current)+".doc";
OperatorWord word = new OperatorWord();
// *****************************************
// 利用HashMap读取数据库中的数据
HashMap map = new HashMap();
map.put("username", "杨攀");
map.put("sex", "男");
map.put("idcard", "431228198701174625");
// ******************************************
word.replaceTemplate("F://test//test.htm", "F://test//" + targetname, map);
}
}
测试类(把excel转为word):
package cn.xsbiz.main;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import sun.java2d.pipe.SpanShapeRenderer.Simple;
/**
*
* 功能:读取 excel 的内容根据wrod模板动态生产 wrod 文档
*
* 标签:$(xxx)
*
* author 妞见妞爱
*
*/
public class RxlsWdocMain {
public static void main(String[] args) {
OperatorWord word = new OperatorWord();
OperatorExcel excel = new OperatorExcel();
File filepath = new File("f://xsjsj//tmp001.xls");
List<Map<String, String>> list = excel.readExcelReList(filepath);
System.out.println("共:"+list.size());
/*
* ****************************************************************
* 下面的循环生产单个 word 的代码..
*
* 业务:excle 有 1000 个人..需要打印出 1000 个人的通知书。(单个的打印、分开管理)
*
* 功能:如果excle 中有 1000条 记录,那么就生成 1000 个word
*
* 思路:
* 1、定义一个标签格式..本例中是:$(xxx)
* 2、在 word 中编辑好模板样式..另存为html模板。(也可以存为其他格式。但是注意编码问题。不然会乱码)
* 3、读取 excel 中的内容并封住为一个容器: list<map<String,String>>
* 4、读取html模板,并根据标签替换内容。再重新写个文件。
*
* ****************************************************************
*
*/
StringBuffer sb = new StringBuffer();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy 年 MM 月 dd 日");
for (int i = 0; i < list.size(); i++) {
Map<String, String> map = list.get(i);
sb.append(map.get("town")).append("-").append(map.get("village")).append("-").append(map.get("name"));
map.put("date", sdf.format(date));
word.replaceTemplate("f://xsjsj//template.htm", "f://xsjsj//doc//"+sb.toString()+".doc", map);
sb.setLength(0);
}
/*
* ****************************************************************
* 下面的一个内容连续的 word 的代码..
*
* 业务:excle 有 1000 个人..需要连续打印出 1000 个人的通知书。
*
* 功能:如果excle 中有 1000条 记录,那么就生成一个 1000 也的 word,
*
* 思路:
* 1、定义一个标签格式..本例中是:$(xxx)
* 2、在 word 中编辑好模板样式..另存为html模板。但是这里要注意,我们要打开 html 的源码,
* 分解源码为:头部和中间、底部等三部分。(底部模板简单。所以我就写在代码中了),
* 3、读取 excel 中的内容并封住为一个容器: list<map<String,String>>
* 4、读取html头部和中间、底部模板,并根据标签替换中间模板内容。替换完后,在加底部文件。重写文件。生成一个连续的有分页符的word
*
*
* ****************************************************************
*
*/
//word.replaceTemplateAll("f://xsjsj//tem_top.htm","f://xsjsj//tem_center.htm", "f://xsjsj//doc2//jisj.doc", list);
}
}
真是辛苦...我发现些文档比代码辛苦多了。。。。哈哈。。。我在上传工程和测试的文档。。。。
需要的下载啊。。。里面的测试文件数据均为测试数据。。如果运行程序..注意文件的名称修改一致。。。。
注意路径问题。。我没有判断啊。。O(∩_∩)O哈哈~
分享到:
相关推荐
- 优点:Word文档通常用于创建结构化的文本,支持丰富的格式设置,方便插入图表、流程图等,适合编写详细、结构化的接口描述。 - 内容结构:一份标准的Word接口文档通常包括接口名称、接口描述、请求方法(GET、...
本程序编写环境.NET 4.0、 VS2010,语言为C#,通过引用... [字段1:联系人] [字段2:联系电话] 根据检测出的字段编辑Word模板文件,添加相应字段的书签到模板文件,然后选择模板文件,最后批量生成Word文档到指定文件夹。
按WORD模板r把EXCEL表生成单个WORD文档按WORD模板r把EXCEL表生成单个WORD文档按WORD模板r把EXCEL表生成单个WORD文档按WORD模板r把EXCEL表生成单个WORD文档按WORD模板r把EXCEL表生成单个WORD文档按WORD模板r把EXCEL表...
通过这种方式,你可以根据业务需求,利用Java和Apache POI库实现Excel数据的批处理,生成大量定制化的Word文档。这个过程对于报告生成、自动化数据导出或者大规模邮件合并等场景非常有用。 这个示例代码只是一个...
Excel批量生产Word文档是一种高效的方法,尤其适用于需要根据固定模板生成多个类似文档的情况。本文档主要介绍了一个使用Excel和Word结合,通过邮件合并功能实现批量生成Word文档的操作流程。 首先,你需要创建一个...
在IT行业中,API(应用...根据项目团队的习惯和偏好,可以选择合适的模板来编写API接口文档,以提高开发效率和协作质量。记得定期更新和维护接口文档,保持其与实际API的一致性,这对于API的可持续管理和维护至关重要。
在Android开发中,Apache POI 是一个非常实用的库,它允许程序员创建、修改和显示Microsoft Office格式的文件,如Word文档(.doc)和Excel工作簿(.xlsx或.xls)。这个工具对于需要在Android应用中处理这些文档的...
在IT领域,编程语言Go(Golang)以...通过理解Excel模板和Word模板的结构,开发者能够构建出一个强大的批量生成工具,提高工作效率。对于希望学习Go语言进行文件处理和自动化任务的IT从业者,这是一个很好的实践案例。
这个描述也可以作为一个概要,概括了文档的主要内容和功能。 标签: 范文/模板/素材 标签部分提供了三个关键词:范文、模板和素材。这三个标签可以帮助我们快速理解这个模板的性质和用途。范文和模板表明这个模板是...
根据Excel中的数据,我们可以动态地生成Word文档的内容,例如根据每一行数据生成一个表格或段落。此外,该源码还提供了批量生成Word文档的功能。通过循环遍历Excel中的每一行数据,我们可以为每一行数据生成一个单独...
windows下,使用python 将Excel中数据批量导出到Word模板中生成新的文件
API接口模板,word版本和Excel版本,用于平常的接口文档
标题“使用VSTO插件将excel数据和图片导出word文档”涉及到的是在Microsoft Office环境中,使用Visual Studio Tools for Office (VSTO) 插件来实现数据和图像从Excel到Word的自动化迁移。VSTO是.NET Framework的一个...
Java语言利用POI读取excel文档,利用Freemarker建立word模板(带图片),excel每一行数据生成单个word文档,再利用POI合并成一个word文档(源码); 博客地址:...
在IT行业中,尤其是在办公自动化领域,常常需要将Excel中的数据自动导入到Word模板中,以实现批量处理和个性化定制文档。这种操作可以大大提升工作效率,减少手动操作带来的错误。本主题将详细介绍如何利用Excel的...
1. **文本处理**:通过VBA可以批量修改文档内容,查找替换特定文字,格式化文本等。 2. **邮件合并**:利用VBA可以实现批量生成个性化文档,如信函、报告等。 3. **宏命令**:与Excel类似,Word也有宏录制功能,...
而指定模板则允许用户根据自己的需求设置Word文档的布局、样式和格式,确保生成的文档符合特定标准或公司规范。 标签“范文/模板/素材 Excel Word xlsdoc”表明这个工具与Excel和Word文件格式密切相关,并且可能...
本案例中的主题是“Excel批量生成多个Excel文档或Word文件”,这涉及到Excel的宏(VBA,Visual Basic for Applications)编程技术。VBA是一种基于Visual Basic的编程语言,它允许用户自定义Excel的功能,实现自动化...
模版生成通常涉及预先定义好的Word文档,其中包含占位符,这些占位符在程序运行时会被动态替换为实际数据。 1. **使用POI读取和编辑Word模板**: - 初始化`Document`对象:首先,你需要加载Word模板文件,这可以...
1、制作Word模板文件、用替换表达式标记需要从Excel中取值的部分,替换表达式为 ${页签号_行号_列号} 2、双击e2w.bat 运行程序 3、选择Excel数据文件、Word模板文件以及Word报告保存路径。 4、点击【生成Word报告...