近段时间做了个用jxl模板生成xls文件,并在文件中增加图片。具体方法如下
一.maven配置:
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls</artifactId>
<version>2.2.8</version>
</dependency>
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls-poi</artifactId>
<version>1.0.7</version>
</dependency>
二.创建基本类:Employee和EmployeePrintDto和EmployeeRelationPrintDto
public class EmployeePrintDto {
private String deadlineDay;
private String money;
private String name;
private String gender;
private String id_0;
private String id_1;
private String id_2;
private String id_3;
private String id_4;
private String id_5;
private String id_6;
private String id_7;
private String id_8;
private String id_9;
private String id_10;
private String id_11;
private String id_12;
private String id_13;
private String id_14;
private String id_15;
private String id_16;
private String id_17;
private String phone;
private String addr;
private String marryStatus;
private String company;
private String comAddr;
private String position;
private String hy_account;
private String com_phone;
private List<EmployeeRelationPrintDto> crs = new ArrayList<EmployeeRelationPrintDto>();
}
public class EmployeeRelationPrintDto {
private String relation_name;
private String relation;
private String relation_pho;
}
public class Employee{
private Long id;
private String no;
private String name;
private Byte gender;
private String identityCard;
private String identityAddr;
private String phone;
private String marryStatus;
private String companyName;
private String companyAddr;
private String companyPhone;
private String position;
private String hyAccount;
private Byte status;
private Date joinTime;
private String positiveTime;
private String contractType;
private String bankName;
private String bankAccount;
private String email;
}
三.创建生成根据模板文件生成Excel的工具类.JxlExportExcelModelUtils
package com.ftk.eloan.service.export.jxl.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import org.jxls.area.Area;
import org.jxls.builder.AreaBuilder;
import org.jxls.builder.xls.XlsCommentAreaBuilder;
import org.jxls.common.CellRef;
import org.jxls.common.Context;
import org.jxls.transform.Transformer;
import org.jxls.util.TransformerFactory;
import org.springframework.stereotype.Component;
import com.ftk.eloan.entity.emp.Employee;
import com.ftk.eloan.service.export.jxl.dto.EmployeePrintDto;
import com.ftk.eloan.service.export.jxl.dto.EmployeeRelationPrintDto;
/**
* Created by frank on 2016/11/30.
*/
@Component
public class JxlExportExcelModelUtils {
public static void main(String[] args){
// @Value("${export.excel.template}")
String template ="D:/pic/model/emp_loan_template.xls";
// private String template ="D:/pic/model/pact_template.xls";
// @Value("${export.excel.output}")
String output = "D:/pic/jxl/emp";
Employee emp = new Employee();
emp.setName("zhang san");
emp.setGender((byte)1 );
emp.setIdentityCard("43020219980128401X");
emp.setPhone("18332456897");
EmployeePrintDto pactPrintDto = EmpPrintConvertUtils.convertEmployee(emp);
try {
JxlExportExcelModelUtils.execute(pactPrintDto,template,output,"test.xls");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@SuppressWarnings("finally")
public static String execute(EmployeePrintDto pactPrintDto,String template,String outputFolder,String fileName) throws Exception {
InputStream in = null;
OutputStream out = null;
String fileNameTemp = null;
try{
in = new FileInputStream(template);
String filePath = outputFolder + File.separator + fileName;
File outputFile = new File(filePath);
outputFile.delete();
if (!outputFile.exists()) {
if (!outputFile.getParentFile().exists()) {
outputFile.getParentFile().mkdirs();
}
outputFile.createNewFile();
}
out = new FileOutputStream(filePath);
Transformer transformer = TransformerFactory.createTransformer(in, out);
AreaBuilder areaBuilder = new XlsCommentAreaBuilder(transformer, true);
List<Area> xlsAreaList = areaBuilder.build();
Area xlsArea = xlsAreaList.get(0);
Context pfcContext = transformer.createInitialContext();
pfcContext.putVar("emp", pactPrintDto);
pfcContext.putVar("rel", new EmployeeRelationPrintDto());
xlsArea.applyAt(new CellRef(xlsArea.getAreaRef().getSheetName() + "!A1"), pfcContext);
xlsArea.processFormulas();
transformer.write();
fileNameTemp = fileName;
}catch(Exception e){
e.printStackTrace();
}finally {
if(in != null) {
in.close();
}
if(out != null) {
out.flush();
out.close();
}
return fileNameTemp;
}
}
}
四.创建对已有excel插入图片的工具类JxlExportImgUtils
package com.ftk.eloan.service.export.jxl.util;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import com.ftk.eloan.entity.emp.Employee;
import com.ftk.eloan.service.export.jxl.dto.EmployeePrintDto;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.WritableImage;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
public class JxlExportImgUtils {
// 添加图片需要增加的默认行数
private static final int DEFAULT_ADD_CELL_SIZE = 20;
public static void main(String[] args) {
String template = "D:/pic/model/emp_loan_template.xls";
String output = "D:/pic/jxl/emp/";
Employee emp = new Employee();
emp.setName("zhang san");
emp.setGender((byte) 1);
emp.setIdentityCard("43020219980128401X");
emp.setPhone("18332456897");
EmployeePrintDto pactPrintDto = EmpPrintConvertUtils.convertEmployee(emp);
try {
String fileName = JxlExportExcelModelUtils.execute(pactPrintDto, template, output, "test2.xls");
File file = new File(output + fileName);
List<File> pictureFiles = new ArrayList() {
{
add(new File("D:/pic/jxl/1.png"));
add(new File("D:/pic/jxl/2.png"));
}
};
addPicture2Excel(file, 1, pictureFiles, 0, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("finally")
public static String addPicture2Excel(File excelFile, int sheetIndex, List<File> pictureFiles, Integer cellRow,
Integer cellCol) {
String fileName = null;
if (excelFile == null || !excelFile.exists() || pictureFiles == null || pictureFiles.size() <= 0) {
return fileName;
}
// 打开文件
Workbook rdBook = null;
WritableWorkbook book = null;
try {
rdBook = Workbook.getWorkbook(excelFile);
book = Workbook.createWorkbook(excelFile, rdBook);
WritableSheet sheet = book.createSheet("身份证图片", 1);
for (int i = 0; i < pictureFiles.size(); i++) {
File file = pictureFiles.get(i);
if (!file.exists() || file.getName().indexOf(".png") < 0) {
continue;
}
try {
addPictureToExcel(sheet, file, cellRow + i * DEFAULT_ADD_CELL_SIZE, cellCol);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
book.write();
fileName = excelFile.getName();
} catch (BiffException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(rdBook != null) {
rdBook.close();
}
try {
if(book != null) {
book.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return fileName;
}
}
/**
* 插入图片到EXCEL
*
* @param picSheet
* sheet
* @param pictureFile
* 图片file对象
* @param cellRow
* 行数
* @param cellCol
* 列数
* @throws Exception
* 例外
*/
private static void addPictureToExcel(WritableSheet picSheet, File pictureFile, Integer cellRow, Integer cellCol)
throws Exception {
// 开始位置
double picBeginCol = cellCol.intValue();
double picBeginRow = cellRow.intValue();
// 图片时间的高度,宽度
double picCellWidth = 0.0;
double picCellHeight = 0.0;
// 读入图片
BufferedImage picImage = ImageIO.read(pictureFile);
// 取得图片的像素高度,宽度
int picWidth = picImage.getWidth();
int picHeight = picImage.getHeight();
// 计算图片的实际宽度
int picWidth_t = picWidth * 32; // 具体的实验值,原理不清楚。
for (int x = 0; x < 1234; x++) {
int bc = (int) Math.floor(picBeginCol + x);
// 得到单元格的宽度
int v = picSheet.getColumnView(bc).getSize();
double offset0_t = 0.0;
if (0 == x)
offset0_t = (picBeginCol - bc) * v;
if (0.0 + offset0_t + picWidth_t > v) {
// 剩余宽度超过一个单元格的宽度
double ratio_t = 1.0;
if (0 == x) {
ratio_t = (0.0 + v - offset0_t) / v;
}
picCellWidth += ratio_t;
picWidth_t -= (int) (0.0 + v - offset0_t);
} else { // 剩余宽度不足一个单元格的宽度
double ratio_r = 0.0;
if (v != 0)
ratio_r = (0.0 + picWidth_t) / v;
picCellWidth += ratio_r;
break;
}
}
// 计算图片的实际高度
int picHeight_t = picHeight * 15;
for (int x = 0; x < 1234; x++) {
int bc = (int) Math.floor(picBeginRow + x);
// 得到单元格的高度
int v = picSheet.getRowView(bc).getSize();
double offset0_r = 0.0;
if (0 == x)
offset0_r = (picBeginRow - bc) * v;
if (0.0 + offset0_r + picHeight_t > v) {
// 剩余高度超过一个单元格的高度
double ratio_q = 1.0;
if (0 == x)
ratio_q = (0.0 + v - offset0_r) / v;
picCellHeight += ratio_q;
picHeight_t -= (int) (0.0 + v - offset0_r);
} else {// 剩余高度不足一个单元格的高度
double ratio_m = 0.0;
if (v != 0)
ratio_m = (0.0 + picHeight_t) / v;
picCellHeight += ratio_m;
break;
}
}
// 生成一个图片对象。
WritableImage image = new WritableImage(picBeginCol, picBeginRow, picCellWidth, picCellHeight, pictureFile);
// 把图片插入到sheet
picSheet.addImage(image);
}
}
五.设置模板文件
注意模板中需要在A1和B13处编辑批注。批注如下:
admin:
jx:area(lastCell="AD28")
admin:
jx:each(items="emp.crs",var="rel",lastCell="AD13")
六.注意事项
jxl只对xls文档操作有效,插入图片只能是png格式的。另外模板需要在excel模板中用批注额外指定域