需求:
现有一个excel文档,该文档从第三行开始,每一行代表一个化石及其相关的登记资料,如图1,现在需要将每一行数据的内容,填写到对应的word文档中,并将入库照片编号对应的照片插入对应位置,如图2,最后要求不能生成单个的word文档,因为文档个数多了,不方便整理和打印,需要合并成一个或者多个;
图1:
图2:
实现思路:
Java语言利用POI读取excel文档,利用Freemarker建立word模板(带图片),循环读取excel每一行数据并生成单个word文档,再利用POI合并成一个word文档。
实现过程:
一、准备模板:参考博客园文章Java 用Freemarker完美导出word文档(带图片)
1、word原件用eclipse或者其他编辑器如Firstobject free XML editor打开;
2、 把需要动态修改的内容替换成********(为了后面方便查找和替换),如果有图片,尽量选择较小的图片几十K左右,并调整好位置(导入图片时,不管什么尺寸的图片,都会按照现在固定好的格式大小及位置导入,也就是会出现图片被拉伸变形,如果没有对应的图片,图片位置会显示如下图);
3、另存为,选择保存类型Word 2003 XML 文档(*.xml)【这里说一下为什么用Microsoft Office Word打开且要保存为Word 2003XML,本人亲测,用WPS找不到Word 2003XML选项,如果保存为Word XML,会有兼容问题,避免出现导出的word文档不能用Word 2003打开的问题】,保存的文件名不要是中文;
4、用Firstobject free XML editor打开文件,选择Tools下的Indent【或者按快捷键F8】格式化文件内容。左边是文档结构,右边是文档内容;
5、 将文档内容中需要动态修改内容的地方,换成freemarker的标识。其实就是Map<String, Object>中key,如${landName}; (注意Map中不能没有对应的key,否则会报错,没有内容的话,value放个空字符串就好了)
6、在加入了图片占位的地方,会看到一片base64编码后的代码,把base64替换成${image},也就是Map<String, Object>中key,值必须要处理成base64;
代码如:<w:binData w:name="wordml://自定义.png" xml:space="preserve">${image}</w:binData>
注意:“>${image}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号。
如果需要循环,则使用:<#list maps as map></#list> maps是Map<String, Object>中key,值为数组,map为自定义;
7、标识替换完之后,模板就弄完了,另存为.ftl后缀文件即可。注意:一定不要用word打开ftl模板文件,否则xml内容会发生变化,导致前面的工作白做了。
二、读取excel---生成word文档---合并word文档(源码下载)
小提示:
1、word前后格式要一致,这里代码可能不兼容doc,所以word原文档先另存为docx格式的,后续生成、合并等都要使用docx;
2、excel读取中,每一行的读取时,不要跳过空格单元格,因为向word中写入时,是按照excel中的位置读取的内容;
3、excel读取时,注意框线,有的话,最好是有内容的行列同意都加框线,尤其注意最后一列,缺少框线时读取会有问题;
主程序:
package e2w;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import sun.misc.BASE64Encoder;
/**
* 读取excel文件,把每一行转换为一个word文档数据
*
* @author 15730
*
*/
public class MainOO {
public static int qishibianhao;
public static File file;
public static String pic_url;
public static void main(String[] args) {
Boolean excel_is_exist=false;
Boolean num_is_right=false;
Boolean pic_url_is_right=false;
while(true){
if(excel_is_exist==false){
Scanner s = new Scanner(System.in);
System.out.println("请输入excel文档完整路径,如:C:/Users/15730/Desktop/excel2word/新建 XLS 工作表 - 副本.xls,并按回车键");
String url = s.nextLine();
file = new File(url);
if(!file.exists()){
System.out.println("您输入的文档不存在!");
continue;
}else{
excel_is_exist=true;
}
}
if(num_is_right==false){
Scanner s = new Scanner(System.in);
System.out.println("请输入文档起始编号,1-9999之间的整数,如果输入1,则编号从M1-0001开始,如果输入123,则编号从M1-0123开始,输入完成后请按回车键");
int num = s.nextInt();
if(num>0&&num<10000){
qishibianhao=num;//记录初始编号
num_is_right=true;
}else{
System.out.println("您输入的内容错误!");
continue;
}
}
//图片所在文件夹
if(pic_url_is_right==false){
Scanner s = new Scanner(System.in);
System.out.println("请输入图片存储的完整文件夹名称,如:C:/Users/15730/Desktop/excel2word/tupian/,并按回车键");
String url = s.nextLine();
File file = new File(url);
if(!file.exists()){
System.out.println("您输入的文件夹错误!");
continue;
}else{
if(file.isDirectory()){
pic_url=url;
pic_url_is_right=true;
}else{
System.out.println("您输入的文件夹错误!");
continue;
}
}
}
//全部准备好后,开始执行
if(excel_is_exist==true&&num_is_right==true&&pic_url_is_right==true){
break;
}
}
try {
if(file==null){
System.out.println("文档不存在");
return;
}
List<List<Object>> list_hang = CreatAndReadExcel.readExcel(file);
System.out.println("---------------------------------------------");
System.out.println("本文档行数:"+list_hang.size());
for (int i = 0; i < list_hang.size(); i++) {
if (i < 2) {
continue;
}
String biaoTouBianHao = getBiaoTouBianHao(qishibianhao++);// 表头编号
List<Object> list_lie = list_hang.get(i);
// System.out.println(list_lie.size());
// System.out.println("---------------------------------------------");
// for(int j=0;j<list_lie.size();j++){
// System.out.println(list_lie.get(j));
// }
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("bianhao", biaoTouBianHao);
// String xuHao = list_lie.get(0).toString();//需要,word用不到
String quDuanHao = list_lie.get(1).toString();// 区段号
map.put("quDuanHao", quDuanHao);
String yeWaiBianHao = list_lie.get(2).toString();// 野外原始编号
map.put("yeWaiBianHao", yeWaiBianHao);
String huaShiBianHao = list_lie.get(3).toString();// 化石编号
map.put("huaShiBianHao", huaShiBianHao);
String huaShiLeiBie = list_lie.get(4).toString();// 化石类别
map.put("huaShiLeiBie", huaShiLeiBie);
String buWeiMingCheng = list_lie.get(5).toString();// 部位名称
map.put("buWeiMingCheng", buWeiMingCheng);
String diCeng = list_lie.get(6).toString();// 地层
map.put("diCeng", diCeng);
String chanDi = list_lie.get(7).toString();// 产 地
map.put("chanDi", chanDi);
// String ruKuShiJian = list_lie.get(8).toString();
// //入库时间,此字段不需要
String huaShiJiBenMiaoShu = list_lie.get(9).toString();// 化石基本描述
map.put("huaShiJiBenMiaoShu", huaShiJiBenMiaoShu);
String ruKuZhaoPianBianHao = list_lie.get(10).toString();// 入库照片编号,根据图片名称,查找图片并插入word
/**
* 临时目录
*/
String src=pic_url+ruKuZhaoPianBianHao+".jpg";
// System.out.println(" ");
// System.out.println(" ---- "+src);
File pic = new File(src);
if(pic.exists()){
map.put("image", getImageBase(src));
}else{
map.put("image", "");
}
// 以下三种保存方式,每个只有一种,前两种需要拆分字符串
String huoJiaBaoCun = list_lie.get(11).toString();// 货架保存
// (架-列-层)
String MiFengGuiBaoCun = list_lie.get(12).toString();// 密集柜保存
// (架-列-层)
String shaCaoBaoCun = list_lie.get(13).toString();// 沙槽保存
// System.out.println("区段号 : " + quDuanHao);
// System.out.println("野外原始编号 : " + yeWaiBianHao);
// System.out.println("化石编号 : " + huaShiBianHao);
// System.out.println("化石类别 : " + huaShiLeiBie);
// System.out.println("部位名称 : " + buWeiMingCheng);
// System.out.println("地层 : " + diCeng);
// System.out.println("产地 : " + chanDi);
// System.out.println("化石基本描述 : " + huaShiJiBenMiaoShu);
// System.out.println("入库照片编号 : " + ruKuZhaoPianBianHao);
// System.out.println("货架保存 (架-列-层) : "+huoJiaBaoCun);
// System.out.println("密集柜保存 (架-列-层) : "+MiFengGuiBaoCun);
if (huoJiaBaoCun != "") {//货架保存
String[] str = huoJiaBaoCun.split("-");
String huoJiaBaoCun_jiahao = str[0];
String huoJiaBaoCun_liehao = str[1];
String huoJiaBaoCun_cenghao = str[2];
// System.out.println("货架保存 (架) : "
// + huoJiaBaoCun_jiahao);
// System.out.println("货架保存 (列) : "
// + huoJiaBaoCun_liehao);
// System.out.println("货架保存 (层) : "
// + huoJiaBaoCun_cenghao);
map.put("huoJiaBaoCun_jiahao", huoJiaBaoCun_jiahao);
map.put("huoJiaBaoCun_liehao", huoJiaBaoCun_liehao);
map.put("huoJiaBaoCun_cenghao", huoJiaBaoCun_cenghao);
map.put("MiFengGuiBaoCun_jiahao",
"");
map.put("MiFengGuiBaoCun_liehao",
"");
map.put("MiFengGuiBaoCun_cenghao",
"");
map.put("shaCaoBaoCun", "");
} else if (MiFengGuiBaoCun != "") {//密集柜保存
String[] str = MiFengGuiBaoCun.split("-");
String MiFengGuiBaoCun_jiahao = str[0];
String MiFengGuiBaoCun_liehao = str[1];
String MiFengGuiBaoCun_cenghao = str[2];
// System.out.println("密集柜保存 (架) : "
// + MiFengGuiBaoCun_jiahao);
// System.out.println("密集柜保存 (列) : "
// + MiFengGuiBaoCun_liehao);
// System.out.println("密集柜保存 (层) : "
// + MiFengGuiBaoCun_cenghao);
map.put("MiFengGuiBaoCun_jiahao",
MiFengGuiBaoCun_jiahao);
map.put("MiFengGuiBaoCun_liehao",
MiFengGuiBaoCun_liehao);
map.put("MiFengGuiBaoCun_cenghao",
MiFengGuiBaoCun_cenghao);
map.put("huoJiaBaoCun_jiahao", "");
map.put("huoJiaBaoCun_liehao", "");
map.put("huoJiaBaoCun_cenghao", "");
map.put("shaCaoBaoCun", "");
} else if (shaCaoBaoCun != "") {//沙槽保存
// System.out.println("沙槽保存 : " + shaCaoBaoCun);
map.put("shaCaoBaoCun", shaCaoBaoCun);
map.put("MiFengGuiBaoCun_jiahao",
"");
map.put("MiFengGuiBaoCun_liehao",
"");
map.put("MiFengGuiBaoCun_cenghao",
"");
map.put("huoJiaBaoCun_jiahao", "");
map.put("huoJiaBaoCun_liehao", "");
map.put("huoJiaBaoCun_cenghao", "");
} else {
System.out.println("第"+(i+1)+"行存在格式问题,请注意检查是否存在少边框或者三种存储方式都为空的情况");
}
WordUtils.exportWord(map, biaoTouBianHao, "map.ftl");
}
}
} catch (IOException e) {
e.printStackTrace();
}
// WordUtils.exportMillCe。rtificateWord(getRequest(),getResponse(),map,"方案","sellPlan.ftl");
}
public static String getBiaoTouBianHao(int i){
String biaoTouBianHao = "M1-";//"M1-0001"
String num = new Integer(i).toString();
String temp="";
switch (num.length()) {
case 1:
temp = "000";
break;
case 2:
temp = "00";
break;
case 3:
temp = "0";
break;
case 4:
temp = "";
break;
default:
break;
}
return biaoTouBianHao+temp+num;
}
//获得图片的base64码
@SuppressWarnings("deprecation")
public static String getImageBase(String src) {
if(src==null||src==""){
return "";
}
File file = new File(src);
if(!file.exists()) {
return "";
}
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
}
excel操作:
package e2w;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* 可以从http://poi.apache.org/ 这里下载到POI的jar�?POI 创建和读�?003-2007版本Excel文件
*
*/
public class CreatAndReadExcel {
public static void main(String[] args) throws Exception {
// creat2003Excel();// 创建2007版Excel文件
// creat2007Excel();// 创建2003版Excel文件
// 读取2003Excel文件
String path2003 = System.getProperty("user.dir")
+ System.getProperty("file.separator") + "style_2003.xls";// 获取项目文件路径
// +2003版文件名
System.out.println("路径:" + path2003);
File f2003 = new File(path2003);
try {
readExcel(f2003);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// //读取2007Excel文件
// String path2007 = System.getProperty("user.dir")
// + System.getProperty("file.separator") + "style_2007.xlsx";//
// 获取项目文件路径+2007版文件名
// // System.out.println("路径�? + path2007);
// File f2007 = new File(path2007);
// try {
// readExcel(f2007);
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
/**
* 创建2007版Excel文件
*
* @throws FileNotFoundException
* @throws IOException
*/
private static void creat2007Excel() throws FileNotFoundException,
IOException {
// HSSFWorkbook workBook = new HSSFWorkbook();// 创建 �?��excel文档对象
XSSFWorkbook workBook = new XSSFWorkbook();
XSSFSheet sheet = workBook.createSheet();// 创建�?��工作薄对�?
sheet.setColumnWidth(0, 10000);// 设置第二列的宽度�?
XSSFRow row = sheet.createRow(1);// 创建�?��行对�?
row.setHeightInPoints(23);// 设置行高23像素
XSSFCellStyle style = workBook.createCellStyle();// 创建样式对象
// 设置字体
XSSFFont font = workBook.createFont();// 创建字体对象
font.setFontHeightInPoints((short) 15);// 设置字体大小
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 设置粗体
font.setFontName("黑体");// 设置为黑体字
style.setFont(font);// 将字体加入到样式对象
// 设置对齐方式
style.setAlignment(HSSFCellStyle.ALIGN_CENTER_SELECTION);// 水平居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
// 设置边框
style.setBorderTop(HSSFCellStyle.BORDER_THICK);// 顶部边框粗线
style.setTopBorderColor(HSSFColor.RED.index);// 设置为红�?
style.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);// 底部边框双线
style.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);// 左边边框
style.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);// 右边边框
// 格式化日�?
style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
XSSFCell cell = row.createCell(1);// 创建单元�?
cell.setCellValue(new Date());// 写入当前日期
cell.setCellStyle(style);// 应用样式对象
// 文件输出�?
FileOutputStream os = new FileOutputStream("style_2007.xlsx");
workBook.write(os);// 将文档对象写入文件输出流
os.close();// 关闭文件输出�?
System.out.println("创建成功 office 2007 excel");
}
/**
* 创建2003版本的Excel文件
*/
public static void creat2003Excel(String path)
throws FileNotFoundException, IOException {
HSSFWorkbook workBook = new HSSFWorkbook();// 创建 一个excel文档对象
HSSFSheet sheet = workBook.createSheet();// 创建 一个工作薄对象?
sheet.setColumnWidth(0, 3000);// 设置第1列的宽度
sheet.setColumnWidth(1, 5000);// 设置第2列的宽度
sheet.setColumnWidth(2, 3000);// 设置第3列的宽度
// HSSFRow row = sheet.createRow(1);// 创建一个行对象
// row.setHeightInPoints(23);// 设置行高23像素
// HSSFCellStyle style = workBook.createCellStyle();// 创建样式对象
// 设置字体
// HSSFFont font = workBook.createFont();// 创建字体对象
// font.setFontHeightInPoints((short) 15);// 设置字体大小
// font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 设置粗体
// font.setFontName("黑体");// 设置为黑体字
// style.setFont(font);// 将字体加入到样式对象
// 设置对齐方式
// style.setAlignment(HSSFCellStyle.ALIGN_CENTER_SELECTION);// 水平居中
//
// style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
// 设置边框
// style.setBorderTop(HSSFCellStyle.BORDER_THICK);// 顶部边框粗线
//
// style.setTopBorderColor(HSSFColor.RED.index);// 设置为红�?
//
// style.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);// 底部边框双线
//
// style.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);// 左边边框
//
// style.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);// 右边边框
// 格式化日�?
// style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
//
// HSSFCell cell = row.createCell(1);// 创建单元�?
// cell.setCellValue(new Date());// 写入当前日期
// cell.setCellStyle(style);// 应用样式对象
// 文件输出�?
FileOutputStream os = new FileOutputStream(path);
workBook.write(os);// 将文档对象写入文件输出流
os.close();// 关闭文件输出�?
// System.out.println("创建成功 office 2003 excel");
}
/**
* 对外提供读取excel 的方�?
*/
public static List<List<Object>> readExcel(File file) throws IOException {
String fileName = file.getName();
String extension = fileName.lastIndexOf(".") == -1 ? "" : fileName
.substring(fileName.lastIndexOf(".") + 1);
if ("xls".equals(extension)) {
return read2003Excel(file);
} /*
* else if ("xlsx".equals(extension)) { return read2007Excel(file); }
*/else {
throw new IOException("不支持的文件类型");
}
}
/**
* 读取 office 2003 excel
*
* @throws IOException
* @throws FileNotFoundException
*/
private static List<List<Object>> read2003Excel(File file)
throws IOException {
List<List<Object>> list = new LinkedList<List<Object>>();
HSSFWorkbook hwb = new HSSFWorkbook(new FileInputStream(file));
HSSFSheet sheet = hwb.getSheetAt(0);
Object value = null;
HSSFRow row = null;
HSSFCell cell = null;
System.out.println("读取office 2003 excel内容如下: ");
for (int i = sheet.getFirstRowNum(); i <= sheet
.getPhysicalNumberOfRows(); i++) {
row = sheet.getRow(i);
if (row == null) {
continue;
}
List<Object> linked = new LinkedList<Object>();
for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {
cell = row.getCell(j);
if (cell == null) {
continue;
}
DecimalFormat df = new DecimalFormat("0");// 格式�?number String
// 字符
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");// 格式化日期字符串
DecimalFormat nf = new DecimalFormat("0.00");// 格式化数�?
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_STRING:
// System.out.println(i + "�? + j + " �?is String type");
value = cell.getStringCellValue();
System.out.print(" " + value + " ");
break;
case XSSFCell.CELL_TYPE_NUMERIC:
// System.out.println(i + "�? + j
// + " �?is Number type ; DateFormt:"
// + cell.getCellStyle().getDataFormatString());
if ("@".equals(cell.getCellStyle().getDataFormatString())) {
value = df.format(cell.getNumericCellValue());
} else if ("General".equals(cell.getCellStyle()
.getDataFormatString())) {
value = nf.format(cell.getNumericCellValue());
} else {
value = sdf.format(HSSFDateUtil.getJavaDate(cell
.getNumericCellValue()));
}
System.out.print(" " + value + " ");
break;
case XSSFCell.CELL_TYPE_BOOLEAN:
// System.out.println(i + "�? + j + " �?is Boolean type");
value = cell.getBooleanCellValue();
System.out.print(" " + value + " ");
break;
case XSSFCell.CELL_TYPE_BLANK:
// System.out.println(i + "�? + j + " �?is Blank type");
value = "";
System.out.print(" " + value + " ");
break;
default:
// System.out.println(i + "�? + j + " �?is default type");
value = cell.toString();
System.out.print(" " + value + " ");
}
/**
* 当一行中的某单元格是空着(不是打了空格)的时候,同样加入到list中,用标题行的列数控制读取的单元格数
* 2019年3月18日
*
*/
// if (value == null || "".equals(value)) {
// continue;
// }
linked.add(value);
}
System.out.println("");
list.add(linked);
}
return list;
}
/**
* 读取Office 2007 excel
*/
/*
* private static List<List<Object>> read2007Excel(File file) throws
* IOException {
*
* List<List<Object>> list = new LinkedList<List<Object>>(); // String path
* = System.getProperty("user.dir") + //
* System.getProperty("file.separator")+"dd.xlsx"; //
* System.out.println("路径�?+path); // 构�? XSSFWorkbook 对象,strPath 传入文件路径
* XSSFWorkbook xwb = new XSSFWorkbook(new FileInputStream(file));
*
* // 读取第一章表格内�? XSSFSheet sheet = xwb.getSheetAt(0); Object value = null;
* XSSFRow row = null; XSSFCell cell = null; System.out.println("读取office
* 2007 excel内容如下�?); for (int i = sheet.getFirstRowNum(); i <= sheet
* .getPhysicalNumberOfRows(); i++) { row = sheet.getRow(i); if (row ==
* null) { continue; } List<Object> linked = new LinkedList<Object>(); for
* (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) { cell =
* row.getCell(j); if (cell == null) { continue; } DecimalFormat df = new
* DecimalFormat("0");// 格式�?number String // 字符 SimpleDateFormat sdf = new
* SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");// 格式化日期字符串 DecimalFormat nf =
* new DecimalFormat("0.00");// 格式化数�?
*
* switch (cell.getCellType()) { case XSSFCell.CELL_TYPE_STRING: //
* System.out.println(i + "�? + j + " �?is String type"); value =
* cell.getStringCellValue(); System.out.print(" " + value + " "); break;
* case XSSFCell.CELL_TYPE_NUMERIC: // System.out.println(i + "�? + j // +
* " �?is Number type ; DateFormt:" // +
* cell.getCellStyle().getDataFormatString()); if
* ("@".equals(cell.getCellStyle().getDataFormatString())) { value =
* df.format(cell.getNumericCellValue());
*
* } else if ("General".equals(cell.getCellStyle() .getDataFormatString()))
* { value = nf.format(cell.getNumericCellValue()); } else { value =
* sdf.format(HSSFDateUtil.getJavaDate(cell .getNumericCellValue())); }
* System.out.print(" " + value + " "); break; case
* XSSFCell.CELL_TYPE_BOOLEAN: // System.out.println(i + "�? + j + " �?is
* Boolean type"); value = cell.getBooleanCellValue(); System.out.print(" "
* + value + " "); break; case XSSFCell.CELL_TYPE_BLANK: //
* System.out.println(i + "�? + j + " �?is Blank type"); value = ""; //
* System.out.println(value); break; default: // System.out.println(i +
* "�? + j + " �?is default type"); value = cell.toString();
* System.out.print(" " + value + " "); } if (value == null ||
* "".equals(value)) { continue; } linked.add(value); }
* System.out.println(""); list.add(linked); } return list; }
*/
}
word操作:
package e2w;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class WordUtils {
// 配置信息,代码本身写的还是很可读的,就不过多注解了
private static Configuration configuration = null;
// 这里注意的是利用WordUtils的类加载器动态获得模板文件的位置
private static final String templateFolder = WordUtils.class
.getClassLoader().getResource("").getPath()
+ "templates/";
// private static final String templateFolder =
// "D:\java_old\workspace\excel2Word\bin\templates";
static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
try {
configuration.setDirectoryForTemplateLoading(new File(
templateFolder));
} catch (IOException e) {
e.printStackTrace();
}
}
private WordUtils() {
throw new AssertionError();
}
// public static void exportMillCertificateWord(HttpServletRequest request,
// HttpServletResponse response, Map map,String title,String ftlFile) throws
// IOException {
// Template freemarkerTemplate = configuration.getTemplate(ftlFile);
// File file = null;
// InputStream fin = null;
// ServletOutputStream out = null;
// try {
// // 调用工具类的createDoc方法生成Word文档
// file = createDoc(map,freemarkerTemplate);
// fin = new FileInputStream(file);
//
// response.setCharacterEncoding("utf-8");
// response.setContentType("application/msword");
// // 设置浏览器以下载的方式处理该文件名
// String fileName = title+DateUtil.formatDateDetailTime(new Date()) +
// ".doc";
// response.setHeader("Content-Disposition", "attachment;filename="
// .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
//
// out = response.getOutputStream();
// byte[] buffer = new byte[512]; // 缓冲区
// int bytesToRead = -1;
// // 通过循环将读入的Word文件的内容输出到浏览器中
// while((bytesToRead = fin.read(buffer)) != -1) {
// out.write(buffer, 0, bytesToRead);
// }
// } finally {
// if(fin != null) fin.close();
// if(out != null) out.close();
// if(file != null) file.delete(); // 删除临时文件
// }
// }
private static File createDoc(Map<?, ?> dataMap, String title,
Template template) {
String fileName = title + ".docx";
File f = new File(fileName);
Template t = template;
try {
// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
t.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}
public static void exportWord(Map<?, ?> map, String title, String ftlFile)
throws IOException {
System.out.println("-------------------- " + templateFolder);
Template freemarkerTemplate = configuration.getTemplate(ftlFile);
// 调用工具类的createDoc方法生成Word文档
File file = createDoc(map, title, freemarkerTemplate);
}
}
word合并:
package e2w;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
/**
* @author: Max
*
* @Date: 2018/6/8
*
* @name: 多个word文件合并,采用poi实现,兼容图片的迁移
*
* @Description:
*/
public class MergeDoc {
public static void main (String[] args) throws Exception {
InputStream in1 = null;
InputStream in2 = null;
InputStream in3 = null;
OPCPackage src1Package = null;
OPCPackage src2Package = null;
OPCPackage src3Package = null;
OutputStream dest = new FileOutputStream("C:/Users/15730/Desktop/excel2word/merge123.docx");
try {
in1 = new FileInputStream("C:/Users/15730/Desktop/excel2word/M1-0001.docx");
in2 = new FileInputStream("C:/Users/15730/Desktop/excel2word/M1-0002.docx");
in3 = new FileInputStream("C:/Users/15730/Desktop/excel2word/M1-0003.docx");
src1Package = OPCPackage.open(in1);
src2Package = OPCPackage.open(in2);
src3Package = OPCPackage.open(in3);
} catch (Exception e) {
e.printStackTrace();
}
XWPFDocument src1Document = new XWPFDocument(src1Package);
XWPFDocument src2Document = new XWPFDocument(src2Package);
XWPFDocument src3Document = new XWPFDocument(src3Package);
appendBody(src1Document, src2Document);
appendBody(src1Document, src3Document);
src1Document.write(dest);
}
public static void appendBody(XWPFDocument src, XWPFDocument append) throws Exception {
CTBody src1Body = src.getDocument().getBody();
CTBody src2Body = append.getDocument().getBody();
List<XWPFPictureData> allPictures = append.getAllPictures();
// 记录图片合并前及合并后的ID
Map<String,String> map = new HashMap();
for (XWPFPictureData picture : allPictures) {
String before = append.getRelationId(picture);
//将原文档中的图片加入到目标文档中
String after = src.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
map.put(before, after);
}
appendBody(src1Body, src2Body,map);
}
private static void appendBody(CTBody src, CTBody append,Map<String,String> map) throws Exception {
XmlOptions optionsOuter = new XmlOptions();
optionsOuter.setSaveOuter();
String appendString = append.xmlText(optionsOuter);
String srcString = src.xmlText();
String prefix = srcString.substring(0,srcString.indexOf(">")+1);
String mainPart = srcString.substring(srcString.indexOf(">")+1,srcString.lastIndexOf("<"));
String sufix = srcString.substring( srcString.lastIndexOf("<") );
String addPart = appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<"));
if (map != null && !map.isEmpty()) {
//对xml字符串中图片ID进行替换
for (Map.Entry<String, String> set : map.entrySet()) {
addPart = addPart.replace(set.getKey(), set.getValue());
}
}
//将两个文档的xml内容进行拼接
CTBody makeBody = CTBody.Factory.parse(prefix+mainPart+addPart+sufix);
src.set(makeBody);
}
}
后记:
在打包程序时,遇到了一些问题,见另外两篇博客:
1、eclipse导出可运行jar包时,双击没反应,命令行中jar命令运行报错“**.jar中没有主清单属性”或者报错“Error: Invalid or corrup jarfile **.jar。
2、MANIFEST.MF文件详解
最后
以上就是烂漫砖头最近收集整理的关于Java语言利用POI读取excel文档,利用Freemarker建立word模板(带图片),excel每一行数据生成单个word文档,再利用POI合并成一个word文档的全部内容,更多相关Java语言利用POI读取excel文档内容请搜索靠谱客的其他文章。
发表评论 取消回复