`
yangpanwww
  • 浏览: 624914 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

根据Excel的内容和Word模板的内容生产Word文档

阅读更多

花了一个下午的时间。磨出来的一个东西..感觉好不错。。拿来分享下。。哈哈。。

 

大体功能是:根据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>&nbsp;</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和excel两种

    - 优点:Word文档通常用于创建结构化的文本,支持丰富的格式设置,方便插入图表、流程图等,适合编写详细、结构化的接口描述。 - 内容结构:一份标准的Word接口文档通常包括接口名称、接口描述、请求方法(GET、...

    将Excel中的数据按照Word模板生成Word文档

    本程序编写环境.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表生成单个WORD文档按WORD模板r把EXCEL表...

    Java通过POI读取Excel遍历数据,批量生成word文档

    通过这种方式,你可以根据业务需求,利用Java和Apache POI库实现Excel数据的批处理,生成大量定制化的Word文档。这个过程对于报告生成、自动化数据导出或者大规模邮件合并等场景非常有用。 这个示例代码只是一个...

    Excel批量生产word文档操作手册

    Excel批量生产Word文档是一种高效的方法,尤其适用于需要根据固定模板生成多个类似文档的情况。本文档主要介绍了一个使用Excel和Word结合,通过邮件合并功能实现批量生成Word文档的操作流程。 首先,你需要创建一个...

    API接口模板-含Word和excel

    在IT行业中,API(应用...根据项目团队的习惯和偏好,可以选择合适的模板来编写API接口文档,以提高开发效率和协作质量。记得定期更新和维护接口文档,保持其与实际API的一致性,这对于API的可持续管理和维护至关重要。

    android中poi生成word文档和excel文档

    在Android开发中,Apache POI 是一个非常实用的库,它允许程序员创建、修改和显示Microsoft Office格式的文件,如Word文档(.doc)和Excel工作簿(.xlsx或.xls)。这个工具对于需要在Android应用中处理这些文档的...

    golang读取excel模板批量生成word工具.zip

    在IT领域,编程语言Go(Golang)以...通过理解Excel模板和Word模板的结构,开发者能够构建出一个强大的批量生成工具,提高工作效率。对于希望学习Go语言进行文件处理和自动化任务的IT从业者,这是一个很好的实践案例。

    Apifox导出word版接口文档-模板

    这个描述也可以作为一个概要,概括了文档的主要内容和功能。 标签: 范文/模板/素材 标签部分提供了三个关键词:范文、模板和素材。这三个标签可以帮助我们快速理解这个模板的性质和用途。范文和模板表明这个模板是...

    python根据excel中的数据批量生成word文档.zip

    根据Excel中的数据,我们可以动态地生成Word文档的内容,例如根据每一行数据生成一个表格或段落。此外,该源码还提供了批量生成Word文档的功能。通过循环遍历Excel中的每一行数据,我们可以为每一行数据生成一个单独...

    Python将Excel中数据批量导出到Word模板中生成新的文件

    windows下,使用python 将Excel中数据批量导出到Word模板中生成新的文件

    API接口模板word/Excel

    API接口模板,word版本和Excel版本,用于平常的接口文档

    使用VSTO插件将excel数据和图片导出word文档

    标题“使用VSTO插件将excel数据和图片导出word文档”涉及到的是在Microsoft Office环境中,使用Visual Studio Tools for Office (VSTO) 插件来实现数据和图像从Excel到Word的自动化迁移。VSTO是.NET Framework的一个...

    POI读取excel,利用Freemarker建立word模板(带图片),生成word文档,再合并成一个word文档(源码)

    Java语言利用POI读取excel文档,利用Freemarker建立word模板(带图片),excel每一行数据生成单个word文档,再利用POI合并成一个word文档(源码); 博客地址:...

    将Excel数据对应写入已做好的Word模板的指定位置_excel_ExcelVBA_

    在IT行业中,尤其是在办公自动化领域,常常需要将Excel中的数据自动导入到Word模板中,以实现批量处理和个性化定制文档。这种操作可以大大提升工作效率,减少手动操作带来的错误。本主题将详细介绍如何利用Excel的...

    【免费下载】ExcelVBA和WordVBA教程.rar

    1. **文本处理**:通过VBA可以批量修改文档内容,查找替换特定文字,格式化文本等。 2. **邮件合并**:利用VBA可以实现批量生成个性化文档,如信函、报告等。 3. **宏命令**:与Excel类似,Word也有宏录制功能,...

    批量将Excel数据表转为指定模板的Word文档明细表

    而指定模板则允许用户根据自己的需求设置Word文档的布局、样式和格式,确保生成的文档符合特定标准或公司规范。 标签“范文/模板/素材 Excel Word xlsdoc”表明这个工具与Excel和Word文件格式密切相关,并且可能...

    excel生成多个excel文档或者word文件20200210.zip

    本案例中的主题是“Excel批量生成多个Excel文档或Word文件”,这涉及到Excel的宏(VBA,Visual Basic for Applications)编程技术。VBA是一种基于Visual Basic的编程语言,它允许用户自定义Excel的功能,实现自动化...

    使用poi根据模版生成word文档并转换成PDF文件

    模版生成通常涉及预先定义好的Word文档,其中包含占位符,这些占位符在程序运行时会被动态替换为实际数据。 1. **使用POI读取和编辑Word模板**: - 初始化`Document`对象:首先,你需要加载Word模板文件,这可以...

    Word文档生产工具(Word模板从Excel中选取数据)

    1、制作Word模板文件、用替换表达式标记需要从Excel中取值的部分,替换表达式为 ${页签号_行号_列号} 2、双击e2w.bat 运行程序 3、选择Excel数据文件、Word模板文件以及Word报告保存路径。 4、点击【生成Word报告...

Global site tag (gtag.js) - Google Analytics