org.jxls
jxls
2.4.5
org.jxls
jxls-poi
1.0.9
org.jxls
jxls-jexcel
1.0.7
3.1.2 生成excel的工具类/工具辅助类
jxls工具辅助类
/**
* 工具辅助类
*/
public class JxlsUtil {
private static final JxlsUtil me = new JxlsUtil();
private JxlsUtil() {
}
/**
* 获取工具类实例
*
* @return
*/
public static JxlsUtil me() {
return me;
}
/**
* 如果字符串为{@code null}、空字符串或仅包含空白字符, 则返回false
*
* @param text 要进行检查的字符串
*/
public boolean hasText(String text) {
return !(text == null || text.length() == 0);
}
/**
* 如果数组为{@code null}或长度为0, 则返回false
*
* @param array 要进行检查的数组
*/
public boolean notEmpty(T[] array) {
return !(array == null || array.length == 0);
}
/**
* 如果数组里包含有{@code null}的元素, 则抛出异常. 注意: 若数组本身为{@code null}则不会进行处理, 直接返回false
*
* @param array 要进行检查的数组
*/
public boolean noNullElements(T[] array) {
if (array != null) {
for (T element : array) {
if (element == null) {
return false;
}
}
}
return true;
}
/**
* 如果集合为{@code null},或者不包含任何元素,则返回false
*
* @param collection 要进行检查的集合
*/
public boolean notEmpty(Collection> collection) {
return !(collection == null || collection.isEmpty());
}
/**
* 如果键值对为{@code null},或者不包含任何键值,则返回false
*
* @param map 要进行检查的键值对
*/
public boolean notEmpty(Map, ?> map) {
return !(map == null || map.isEmpty());
}
/**
* 日期格式化
*
* @param date
* @param fmt
* @return
*/
public String dateFmt(Date date, String fmt) {
if (date == null) {
return null;
}
try {
SimpleDateFormat dateFmt = new SimpleDateFormat(fmt);
return dateFmt.format(date);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 数字格式化
*
* @param number
* @param format
* @return
*/
public String numFmt(Number number, String format) {
DecimalFormat dFormat = new DecimalFormat(format);
return dFormat.format(number);
}
/**
* 返回第一个不为空的对象
*
* @param objs
* @return
*/
public Object getNotNull(Object... objs) {
for (Object o : objs) {
if (o != null) {
return o;
}
}
return null;
}
/**
* if判断
*
* @param b
* @param o1
* @param o2
* @return
*/
public Object ifelse(boolean b, Object o1, Object o2) {
return b ? o1 : o2;
}
/**
* 将图片转成数据
*
* @param path 图片绝对路径
* @return
*/
public byte[] getImageData(String path) throws IOException {
try (InputStream ins = new FileInputStream(path)) {
return IOUtils.toByteArray(ins);
}
}
/**
* 获取图片后缀
*
* @param name 图片路径或名称
* @return
*/
public String getImageType(String name) {
int index = name.lastIndexOf(".");
if (index > 0) {
return name.substring(index + 1);
}
return null;
}
/**
* 将图片转成JxlsImage数据对象
*
* @param imgPath 图片路径
* @return
*/
public JxlsImage getJxlsImage(String imgPath) throws IOException {
JxlsImage img = new JxlsImage();
img.setPictureData(getImageData(imgPath));
img.setPictureType(getImageType(imgPath));
return img;
}
/**
* 将图片转成JxlsImage数据对象
* @param is
* @param name
* @return
* @throws IOException
*/
public JxlsImage getJxlsImage(InputStream is, String name) throws IOException {
JxlsImage img = new JxlsImage();
img.setPictureData(IOUtils.toByteArray(is));
img.setPictureType(getImageType(name));
return img;
}
/**
* 判断路径是否是绝对路径
*
* @param path
* @return
*/
public boolean isAbsolutePath(String path) {
return (path.startsWith("/") || path.contains(":"));
}
/**
* 获取集合中的元素
*
* @param index
* @param array
* @return
*/
public T get(int index, T[] array) {
if (notEmpty(array)) {
return array[index];
}
return null;
}
/**
* 获取集合中的元素
*
* @param index
* @param list
* @return
*/
public Object get(int index, List> list) {
if (notEmpty(list)) {
return list.get(index);
}
return null;
}
/**
* 获取集合中的元素
*
* @param key
* @param map
* @return
*/
public Object get(Object key, Map, ?> map) {
if (notEmpty(map)) {
return map.get(key);
}
return null;
}
}
jxsl配置类
public class JxlsConfig {
/** 模板存放目录 */
private static String templateRoot;
/** 默认图片目录 */
private static String imageRoot;
/** 忽略warn警告 */
private static boolean silent = false;
/** 锁住配置 */
private static boolean lock = false;
static{
JxlsConfig.config()
//锁住配置,不能再修改
// .lock()
//设置模板文件根目录
// .templateRoot("jxls_templates")
.templateRoot("excel")
//设置图片路径根目录
.imageRoot("jxls_images");
}
private JxlsConfig(){ }
public static JxlsConfig config(){
if(lock){
throw new IllegalArgumentException("jxls配置已设置锁住,不能再修改");
}
return new JxlsConfig();
}
public JxlsConfig templateRoot(String templateRoot) {
JxlsConfig.templateRoot = getRealPath(templateRoot);
return this;
}
public JxlsConfig imageRoot(String imageRoot) {
JxlsConfig.imageRoot = getRealPath(imageRoot);
return this;
}
public JxlsConfig silent(boolean silent) {
JxlsConfig.silent = silent;
return this;
}
public JxlsConfig lock() {
JxlsConfig.lock = true;
return this;
}
private String getRealPath(String originalPath){
if(!JxlsUtil.me().isAbsolutePath(originalPath) && !originalPath.startsWith("classpath:/")){
URL resource = JxlsConfig.class.getClassLoader().getResource(originalPath);
if(resource != null){
String path = resource.getPath();
if(path.contains(".jar")){
int index = path.lastIndexOf("/", path.indexOf("!/BOOT-INF"));
path = path.substring(0, index).replaceFirst("file:/", "");
File file = new File(path + "/" + originalPath);
if(file.exists()){
return file.getAbsolutePath();
}
originalPath = "classpath:/" + originalPath;
} else {
originalPath = path;
}
}
}
return originalPath;
}
public static String getTemplateRoot() {
return templateRoot;
}
public static String getImageRoot() {
return imageRoot;
}
public static boolean getSilent() {
return silent;
}
}
jxls生成excel辅助类
public abstract class JxlsBuilder {
public static final String EXCEL_SUFFIX = ".xls";
static {
//注册 jx 命令
XlsCommentAreaBuilder.addCommandMapping("merge", MergeCommand.class);
XlsCommentAreaBuilder.addCommandMapping("image", ImageCommand.class);
XlsCommentAreaBuilder.addCommandMapping("keep", KeepCommand.class);
XlsCommentAreaBuilder.addCommandMapping("grid", GridCommand.class);
}
private JxlsHelper jxlsHelper = JxlsHelper.getInstance();
private Transformer transformer;
private Context context;
private InputStream in;
private OutputStream out;
private File inFile;
private File outFile;
private Map funcs;
private String imageRoot = JxlsConfig.getImageRoot();
private boolean ignoreImageMiss = false;
private String[] removeSheetNames;
private JxlsBuilder() {
context = new Context();
funcs = new HashMap<>();
funcs.put("jxu", JxlsUtil.me());
}
private JxlsBuilder(InputStream in) {
this();
this.in = in;
}
private JxlsBuilder(File inFile) {
this();
if (!inFile.exists()) {
throw new IllegalArgumentException("模板文件不存在:" + inFile.getAbsolutePath());
}
if (!inFile.getName().toLowerCase().endsWith("xls") &&
!inFile.getName().toLowerCase().endsWith("xlsx")) {
throw new IllegalArgumentException("不支持非excel文件:" + inFile.getName());
}
this.inFile = inFile;
try {
in = new FileInputStream(inFile);
} catch (FileNotFoundException e) {
throw new IllegalArgumentException("文件读取失败:" + inFile.getAbsolutePath(), e);
}
}
/**
* @param in 模板文件流
* @return
*/
public static JxlsBuilder getBuilder(InputStream in) {
return new JxlsBuilderImpl(in);
}
/**
* @param templateFile 模板文件地址
* @return
*/
public static JxlsBuilder getBuilder(File templateFile) {
return new JxlsBuilderImpl(templateFile);
}
/**
* @param filePath 模板文件路径,可以是绝对路径,也可以是模板存放目录的文件名
* @return
*/
public static JxlsBuilder getBuilder(String filePath) {
//判断是相对路径还是绝对路径
if (!JxlsUtil.me().isAbsolutePath(filePath)) {
if (JxlsConfig.getTemplateRoot().startsWith("classpath:")) {
//文件在jar包内
String templateRoot = JxlsConfig.getTemplateRoot().replaceFirst("classpath:", "");
InputStream resourceAsStream = JxlsBuilder.class.getResourceAsStream(templateRoot + "/" + filePath);
return new JxlsBuilderImpl(resourceAsStream);
} else {
//相对路径就从模板目录获取文件
return new JxlsBuilderImpl(new File(JxlsConfig.getTemplateRoot() +
File.separator + filePath));
}
} else {
//绝对路径
return new JxlsBuilderImpl(new File(filePath));
}
}
public JxlsHelper getJxlsHelper() {
return jxlsHelper;
}
/**
* 生成excel文件
*
* @return
* @throws Exception
*/
public JxlsBuilder build() throws Exception {
getTransformer();
if (JxlsUtil.me().hasText(imageRoot)) {
context.putVar("_imageRoot", imageRoot);
}
context.putVar("_ignoreImageMiss", ignoreImageMiss);
JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) jxlsHelper.createExpressionEvaluator(null);
evaluator.getJexlEngine().setFunctions(funcs);
evaluator.getJexlEngine().setSilent(JxlsConfig.getSilent());
transform();
return this;
}
private void transform() throws Exception {
jxlsHelper.getAreaBuilder().setTransformer(transformer);
List xlsAreaList = jxlsHelper.getAreaBuilder().build();
Iterator var4 = xlsAreaList.iterator();
while (var4.hasNext()) {
Area xlsArea = (Area) var4.next();
xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), context);
if (jxlsHelper.isProcessFormulas()) {
FormulaProcessor fp;
if (jxlsHelper.isUseFastFormulaProcessor()) {
fp = new FastFormulaProcessor();
} else {
fp = new StandardFormulaProcessor();
}
xlsArea.setFormulaProcessor(fp);
xlsArea.processFormulas();
}
}
if (JxlsUtil.me().notEmpty(removeSheetNames)) {
for (String sheetName : removeSheetNames) {
transformer.deleteSheet(sheetName);
}
}
transformer.deleteSheet("Sheet");
transformer.write();
}
private static class JxlsBuilderImpl extends JxlsBuilder {
public JxlsBuilderImpl(InputStream in) {
super(in);
}
public JxlsBuilderImpl(File inFile) {
super(inFile);
}
}
public Transformer getTransformer() throws Exception {
if (transformer == null) {
if (out == null && outFile == null) {
throw new Exception("请指定文件输出位置");
}
if (out == null) {
out = new FileOutputStream(outFile);
}
transformer = jxlsHelper.setUseFastFormulaProcessor(false).createTransformer(in, out);
// transformer = jxlsHelper.setUseFastFormulaProcessor(true).createTransformer(in, out);
}
return transformer;
}
/**
* 指定输出流
*
* @param out
* @return
*/
public JxlsBuilder out(OutputStream out) {
this.out = out;
return this;
}
/**
* 指定输出文件
*
* @param outFile
* @return
*/
public JxlsBuilder out(File outFile) {
this.outFile = outFile;
return this;
}
/**
* 指定输出文件绝对路径
*
* @param outPath
* @return
*/
public JxlsBuilder out(String outPath) {
this.outFile = new File(outPath);
return this;
}
/**
* 添加数据
*
* @param name
* @param value
* @return
*/
public JxlsBuilder putVar(String name, Object value) {
context.putVar(name, value);
return this;
}
/**
* 添加数据
*
* @param map
* @return
*/
public JxlsBuilder putAll(Map map) {
for (String key : map.keySet()) {
putVar(key, map.get(key));
}
return this;
}
/**
* 删除数据
*
* @param name
* @return
*/
public JxlsBuilder removeVar(String name) {
context.removeVar(name);
return this;
}
/**
* 获取数据
*
* @param name
* @return
*/
public Object getVar(String name) {
return context.getVar(name);
}
/**
* 添加自定义工具对象
*
* @param name
* @param function
* @return
*/
public JxlsBuilder addFunction(String name, Object function) {
funcs.put(name, function);
return this;
}
/**
* 设置图片根路径
*
* @param root
* @return
*/
public JxlsBuilder imageRoot(String root) {
this.imageRoot = root;
return this;
}
/**
* 设置是否忽略图片错误
* true 忽略图片错误,如果图片读取失败时不终止运行,继续生成excel
* false 默认,不忽略图片错误,如果图片读取失败终止生成excel
*
* @param ignoreImageMiss
*/
public JxlsBuilder ignoreImageMiss(boolean ignoreImageMiss) {
this.ignoreImageMiss = ignoreImageMiss;
return this;
}
public File getInFile() {
return inFile;
}
public File getOutFile() {
return outFile;
}
public static void main(String[] args) throws Exception {
JxlsBuilder.getBuilder("xx.xlsx")
.out("D:/xx.xlsx")
.putVar("", null)
.build();
}
/**
* 生成excel后删除指定表格
*
* @param sheetNames
* @return
*/
public JxlsBuilder removeSheet(String... sheetNames) {
this.removeSheetNames = sheetNames;
return this;
}
}
如果生成的excel报表有图片可添加excel图片处理类(可不添加)
public class JxlsImage {
public static final String IMAGE_SIZE_TYPE_AUTO = "auto";
public static final String IMAGE_SIZE_TYPE_ORIGINAL = "original";
private byte[] pictureData;
private String pictureType;
public byte[] getPictureData() {
return pictureData;
}
public void setPictureData(byte[] pictureData) {
this.pictureData = pictureData;
}
public String getPictureType() {
return pictureType;
}
public void setPictureType(String pictureType) {
this.pictureType = pictureType;
}
public int getWorkbookImageType() {
switch (pictureType.toUpperCase()) {
case "PNG":
return Workbook.PICTURE_TYPE_PNG;
case "EMF":
return Workbook.PICTURE_TYPE_EMF;
case "WMF":
return Workbook.PICTURE_TYPE_WMF;
case "PICT":
return Workbook.PICTURE_TYPE_PICT;
case "DIB":
return Workbook.PICTURE_TYPE_DIB;
default:
return Workbook.PICTURE_TYPE_JPEG;
}
}
public ImageType getJxlsImageType() {
if ("jpg" .equalsIgnoreCase(pictureType)) {
return ImageType.JPEG;
}
return ImageType.valueOf(pictureType);
}
}
3.1.2 对excel文件格式规范,操作等辅助类
对行操作的规范配置
public class GridCommand extends org.jxls.command.GridCommand {
@Override
public Size applyAt(CellRef cellRef, Context context) {
String props = getProps();
if(!StringUtils.contains(props, ",")){
Object value = getTransformationConfig().getExpressionEvaluator().evaluate(props, context.toMap());
if(value instanceof String){
props = (String) value;
} else if (value instanceof String[]){
props = StringUtils.join((String[]) value, ",");
} else {
throw new IllegalArgumentException("props 属性只支持 String 和 String[]");
}
setProps(props);
}
return super.applyAt(cellRef, context);
}
}
保持单元格样式配置
public class KeepCommand extends AbstractCommand {
private Area area;
public KeepCommand() {
}
@Override
public Command addArea(Area area) {
if( super.getAreaList().size() >= 1){
throw new IllegalArgumentException("You can add only a single area to 'keep' command");
}
this.area = area;
return super.addArea(area);
}
@Override
public String getName() {
return "keep";
}
@Override
public Size applyAt(CellRef cellRef, Context context) {
if( area == null ){
throw new IllegalArgumentException("No area is defined for keep command");
}
//恢复原有的样式
area.applyAt(cellRef, context);
return area.getSize();
}
}
合并单元格配置
/**
* 合并单元格
* jx:merge(
* lastCell="单元格"
* [, cols="合并的列数"]
* [, rows="合并的行数"]
* [, minCols="最小合并的列数"]
* [, minRows="最小合并的行数"]
* )
*/
public class MergeCommand extends AbstractCommand{
private String cols; //合并的列数
private String rows; //合并的行数
private String minCols; //最小合并的列数
private String minRows; //最小合并的行数
private CellStyle cellStyle;//第一个单元格的样式
private Area area;
@Override
public String getName() {
return "merge";
}
@Override
public Command addArea(Area area) {
if (super.getAreaList().size() >= 1) {
throw new IllegalArgumentException("You can add only a single area to 'merge' command");
}
this.area = area;
return super.addArea(area);
}
@Override
public Size applyAt(CellRef cellRef, Context context) {
int rows = getVal(this.rows, context);
int cols = getVal(this.cols, context);
rows = Math.max(getVal(this.minRows, context), rows);
cols = Math.max(getVal(this.minCols, context), cols);
rows = rows > 0 ? rows : area.getSize().getHeight();
cols = cols > 0 ? cols : area.getSize().getWidth();
if(rows > 1 || cols > 1){
Transformer transformer = this.getTransformer();
if(transformer instanceof PoiTransformer){
poiMerge(cellRef, context, (PoiTransformer)transformer, rows, cols);
}else if(transformer instanceof JexcelTransformer){
jexcelMerge(cellRef, context, (JexcelTransformer)transformer, rows, cols);
}
}
area.applyAt(cellRef, context);
return new Size(cols, rows);
}
protected Size poiMerge(CellRef cellRef, Context context, PoiTransformer transformer, int rows, int cols){
Sheet sheet = transformer.getWorkbook().getSheet(cellRef.getSheetName());
CellRangeAddress region = new CellRangeAddress(
cellRef.getRow(),
cellRef.getRow() + rows - 1,
cellRef.getCol(),
cellRef.getCol() + cols - 1);
sheet.addMergedRegion(region);
//合并之后单元格样式会丢失,以下操作将合并后的单元格恢复成合并前第一个单元格的样式
area.applyAt(cellRef, context);
if(cellStyle == null){
PoiCellData cellData = (PoiCellData)transformer.getCellData(area.getStartCellRef());
if(cellData != null){
cellStyle = cellData.getCellStyle();
}
}
setRegionStyle(cellStyle, region, sheet);
return new Size(cols, rows);
}
protected Size jexcelMerge(CellRef cellRef, Context context, JexcelTransformer transformer, int rows, int cols){
try {
transformer.getWritableWorkbook().getSheet(cellRef.getSheetName())
.mergeCells(
cellRef.getRow(),
cellRef.getCol(),
cellRef.getRow() + rows - 1 ,
cellRef.getCol() + cols - 1);
area.applyAt(cellRef, context);
} catch (WriteException e) {
throw new IllegalArgumentException("合并单元格失败");
}
return new Size(cols, rows);
}
private static void setRegionStyle(CellStyle cs, CellRangeAddress region, Sheet sheet) {
for (int i = region.getFirstRow(); i <= region.getLastRow(); i++) {
Row row = sheet.getRow(i);
if (row == null) {
row = sheet.createRow(i);
}for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
Cell cell = row.getCell(j);
if (cell == null) {
cell = row.createCell(j);
}
if (cs == null){
cell.getCellStyle().setAlignment(CellStyle.ALIGN_CENTER);
cell.getCellStyle().setVerticalAlignment(CellStyle.VERTICAL_CENTER);
}else {
cell.setCellStyle(cs);
}
}
}
}
private int getVal(String expression, Context context){
if(JxlsUtil.me().hasText(expression)){
Object obj = getTransformationConfig().getExpressionEvaluator().evaluate(expression, context.toMap());
try {
return Integer.parseInt(obj.toString());
} catch (NumberFormatException e) {
throw new IllegalArgumentException("表达式:" + expression + " 解析失败");
}
}
return 0;
}
public String getCols() {
return cols;
}
public void setCols(String cols) {
this.cols = cols;
}
public String getRows() {
return rows;
}
public void setRows(String rows) {
this.rows = rows;
}
public String getMinCols() {
return minCols;
}
public void setMinCols(String minCols) {
this.minCols = minCols;
}
public String getMinRows() {
return minRows;
}
public void setMinRows(String minRows) {
this.minRows = minRows;
}
}
插入图片配置
/**
* 插入图片
* jx:image(
* src="byte[] | JxlsImage | 图片路径(相对图片目录或绝对绝对路径)",
* lastCell="图片右下角单元格坐标,左上角坐为指令所在单元格"
* [,imageType="JPG"]
* [,size="auto | original"]
* [,scaleX="1"]
* [,scaleY="1"]
* )
*/
public class ImageCommand extends AbstractCommand {
private byte[] imageBytes;
private ImageType imageType = ImageType.PNG;
private Area area;
/**
* 图片源,可以byte[]、JxlsImage对象和图片路径
*/
private String src;
/**
* 插入图片大小,poi4.0以上适用
* @see Picture.resize(scaleX,scaleY)
*/
private String scaleX;
private String scaleY;
/**
* 自适应大小类型
* auto 默认,自适应单元格大小
* original 图片原大小
*/
private String size;
public ImageCommand() {
}
public ImageCommand(String image, ImageType imageType) {
this.src = image;
this.imageType = imageType;
}
public ImageCommand(byte[] imageBytes, ImageType imageType) {
this.imageBytes = imageBytes;
this.imageType = imageType;
}
@Override
public Command addArea(Area area) {
if( super.getAreaList().size() >= 1){
throw new IllegalArgumentException("You can add only a single area to 'image' command");
}
this.area = area;
return super.addArea(area);
}
@Override
public String getName() {
return "image";
}
@Override
public Size applyAt(CellRef cellRef, Context context) {
if( area == null ){
throw new IllegalArgumentException("No area is defined for image command");
}
Transformer transformer = getTransformer();
Size size = area.getSize();
try {
JxlsImage img = getImage(context);
if(img != null){
if(transformer instanceof PoiTransformer){
addImage(cellRef, context, (PoiTransformer) transformer, img);
}else{
//获取图片显示区域是时候,多加一行和一列,获取完之后再恢复原来大小
size.setWidth(size.getWidth() + 1);
size.setHeight(size.getHeight() + 1);
AreaRef areaRef = new AreaRef(cellRef, size);
size.setWidth(size.getWidth() - 1);
size.setHeight(size.getHeight() - 1);
transformer.addImage(areaRef, img.getPictureData(), img.getJxlsImageType());
}
}
} catch (Exception e) {
Boolean ignoreImageMiss = (Boolean) context.getVar("_ignoreImageMiss");
//是否忽略图片读取失败,并继续生成excel后面操作,否则终止生成
if(ignoreImageMiss == null || !ignoreImageMiss){
throw new IllegalArgumentException("出现异常,终止生成excel", e);
}
}
//恢复原有的样式
area.applyAt(cellRef, context);
return size;
}
private void addImage(CellRef cellRef, Context context, PoiTransformer transformer, JxlsImage img){
Workbook wb = transformer.getWorkbook();
int pictureIdx = wb.addPicture(img.getPictureData(), img.getWorkbookImageType());
Sheet sheet = wb.getSheet(cellRef.getSheetName());
Drawing drawing = sheet.createDrawingPatriarch();
CreationHelper helper = wb.getCreationHelper();
ClientAnchor anchor = helper.createClientAnchor();
anchor.setCol1(cellRef.getCol());
anchor.setCol2(cellRef.getCol() + area.getSize().getWidth());
anchor.setRow1(cellRef.getRow());
anchor.setRow2(cellRef.getRow() + area.getSize().getHeight());
Picture pict = drawing.createPicture(anchor, pictureIdx);
if(JxlsUtil.me().hasText(scaleX) || JxlsUtil.me().hasText(scaleY)){
// double scale_x = 1d, scale_y = 1d;
// if(JxlsUtil.me().hasText(scaleX)){
// Object scaleXObj = getTransformationConfig().getExpressionEvaluator().evaluate(scaleX, context.toMap());
// scale_x = Double.valueOf(scaleXObj.toString());
// }
// if(JxlsUtil.me().hasText(scaleY)){
// Object scaleXObj = getTransformationConfig().getExpressionEvaluator().evaluate(scaleY, context.toMap());
// scale_y = Double.valueOf(scaleXObj.toString());
// }
// pict.resize(scale_x, scale_y);
}else if(JxlsImage.IMAGE_SIZE_TYPE_ORIGINAL.equalsIgnoreCase(size)){
pict.resize();
}else{
pict.resize(1d);
}
}
private JxlsImage getImage(Context context) throws IOException {
if(imageBytes == null && src != null){
Object imgObj = getTransformationConfig().getExpressionEvaluator().evaluate(src, context.toMap());
if(imgObj != null){
if(imgObj instanceof byte[]) {
imageBytes = (byte[]) imgObj;
}else if(imgObj instanceof JxlsImage) {
return (JxlsImage) imgObj;
}else if(imgObj instanceof String){
String imgSrc = (String) imgObj;
String imageRoot = (String)context.getVar("_imageRoot");
//判断是相对路径还是绝对路径
if (!JxlsUtil.me().isAbsolutePath(imgSrc)) {
if(imageRoot.startsWith("classpath:")){
//文件在jar包内
String templateRoot = imageRoot.replaceFirst("classpath:", "");
InputStream resourceAsStream = JxlsBuilder.class.getResourceAsStream(templateRoot +
File.separator + imgSrc);
return JxlsUtil.me().getJxlsImage(resourceAsStream, imgSrc);
}else{
//相对路径就从模板目录获取文件
return JxlsUtil.me().getJxlsImage(imageRoot + File.separator + imgSrc);
}
} else {
//绝对路径
return JxlsUtil.me().getJxlsImage(imgSrc);
}
}
}
}
if(imageBytes != null){
JxlsImage img = new JxlsImage();
img.setPictureData(imageBytes);
if(imageType != null){
img.setPictureType(imageType.toString());
}else{
img.setPictureType("jpg");
}
return img;
}
throw new IllegalArgumentException("图片读取失败 " + JxlsUtil.me().getNotNull(src, ""));
}
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
public void setImageType(String strType){
imageType = ImageType.valueOf(strType);
}
public String getScaleX() {
return scaleX;
}
public void setScaleX(String scaleX) {
this.scaleX = scaleX;
}
public String getScaleY() {
return scaleY;
}
public void setScaleY(String scaleY) {
this.scaleY = scaleY;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
}
3.2 使用jxls生成excel报表并导出
3.2.1 写导出报表接口
public Object exportCourseList(List courseIds) throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
HttpHeaders httpHeaders = new HttpHeaders();
List courseBases=new ArrayList<>();
if (CollectionUtils.isNotEmpty(courseIds)){
List baseInfos = this.getByCourseIds(courseIds);
courseBases = baseInfos.stream().map(x->{
DmtCourseBaseinfoDto.ExportCourseBase dto =new DmtCourseBaseinfoDto.ExportCourseBase();
BeanUtils.copyProperties(x,dto);
dto.setStatusName(CourseStatus.getNameByCode(x.getStatus()));
return dto;
}).collect(Collectors.toList());
}
//获取excel模板
ClassPathResource classPathResource = new ClassPathResource("excel/courseList.xlsx");
File template =classPathResource.getFile();
JxlsBuilder.getBuilder(template)
.out(os)
.putVar("list", courseBases)
.build();
httpHeaders.add("Content-Disposition", "attachment;filename=" + new String(("课程列表信息" + IdWorker.getIdStr() +
".xlsx"
//获取excel模板
).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
httpHeaders.add("Content-Length", String.valueOf(os.size()));
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<>(os.toByteArray(), httpHeaders, HttpStatus.OK);
}
3.2.2 excel报表模板创建
创建注意事项:
(1)在A1单元格添加批注(定义区域,需包含所有涉及的单元格)
(2)在需要循环数据的第一行第一列添加批注,如模板所示,我们需要在第二行循环数据填充,那么我们需要在A2单元格添加下列批注(items为循环的集合名称,var为集合别名,lastCell为当前循环的生效区域)
(3)序号可直接使用=ROW(A2)-1来设置
(4)部分单元格如果需要设置格式,可现在模板中直接设置,如需要设置日期格式,可直接在对应单元格设置单元格格式为日期
(5)模板中列表的字段名需要与代码的字段名匹配,并且模板的字段名需要使用对应的格式 如${c.courseName}