jxls中jxlsHelper無法刪除模板問題
阿新 • • 發佈:2018-12-09
/這是zos的輸出流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(bos);
//迴圈
for (xxx:xxxxx) {
//****業務程式碼
//定義檔案的輸入流
InputStream input = EnvUtils.isDevFromSystem() ?
this.getClass().getClassLoader().getResourceAsStream(
WmsConstant.WMS_TEMPLATE_ROOT + filename) :
new FileInputStream(WmsPathUtil.getTemplateReportPath().resolve(filename).toFile());
//定義檔案的輸出流,但是這是作為zip流的一部分
ByteArrayOutputStream output = new ByteArrayOutputStream();
//用jxlsHelper來處理xlxs輸出了流
JxlsHelper jxlsHelper = new WmsJxlsHelper();
jxlsHelper.processTemplate(input, output, context);
//命名檔案
zos.putNextEntry(new ZipEntry(channelName + ".xlsx"));
//把xlxs輸出流作為輸入流輸入到zip輸出流中
zos.write(output.toByteArray());
zos.closeEntry();
output.close();
}
//關閉zos,但是outputStream流依然存在記憶體中
zos.close ();
return genResponseEntityFromBytes(MediaType.APPLICATION_OCTET_STREAM,
downloadFileName, bos.toByteArray());
問題:excel生成時template不能刪除,在查詢jxlsHelper#processTemplate 官方文當的過程中有api
jxlsHelper.setDeleteTemplateSheet(isDeleteTemplateSheet);
jxlsHelper.setHideTemplateSheet(isDeleteTemplateSheet);
然而,設定後根本就沒啥用。 參考原始碼:
//呼叫的api
public JxlsHelper processTemplate(InputStream templateStream, OutputStream targetStream, Context context) throws IOException {
Transformer transformer = this.createTransformer(templateStream, targetStream);
this.processTemplate(context, transformer);
return this;
}
//實際執行的api函式
public void processTemplate(Context context, Transformer transformer) throws IOException {
this.areaBuilder.setTransformer(transformer);
List<Area> xlsAreaList = this.areaBuilder.build();
Iterator var4 = xlsAreaList.iterator();
Area xlsArea;
while(var4.hasNext()) {
xlsArea = (Area)var4.next();
xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), context);
}
if (this.processFormulas) {
var4 = xlsAreaList.iterator();
while(var4.hasNext()) {
xlsArea = (Area)var4.next();
this.setFormulaProcessor(xlsArea);
xlsArea.processFormulas();
}
}
//輸出了excel,有刪除嗎?有用到deleteTemplateSheet或者hideTemplateSheet引數嗎?沒有!
transformer.write();
}
public class CusJxlsHelper extends JxlsHelper {
private static Logger logger = LoggerFactory.getLogger(WmsJxlsHelper.class);
public static WmsJxlsHelper instance() {
return new WmsJxlsHelper();
}
//重寫了processTemplate這個方法
@Override
public void processTemplate(Context context, Transformer transformer) throws IOException {
AreaBuilder areaBuilder = this.getAreaBuilder();
boolean processFormulas = this.isProcessFormulas();
areaBuilder.setTransformer(transformer);
List<Area> xlsAreaList = areaBuilder.build();
Iterator var4 = xlsAreaList.iterator();
Area xlsArea;
while (var4.hasNext()) {
xlsArea = (Area) var4.next();
xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), context);
}
if (processFormulas) {
var4 = xlsAreaList.iterator();
while (var4.hasNext()) {
xlsArea = (Area) var4.next();
this.setFormulaProcessor(xlsArea);
xlsArea.processFormulas();
}
}
//增加了刪除template sheet的業務控制
logger.info("===================delete template sheet in WmsJxlsHelper");
if (this.isDeleteTemplateSheet()) {
transformer.deleteSheet("TEMPLATE");
}
transformer.write();
}
//這裡不想寫的,但是不寫會報錯
private Area setFormulaProcessor(Area xlsArea) {
FormulaProcessor fp = this.getFormulaProcessor();
if (fp == null) {
if (this.isUseFastFormulaProcessor()) {
fp = new FastFormulaProcessor();
} else {
fp = new StandardFormulaProcessor();
}
}
xlsArea.setFormulaProcessor((FormulaProcessor) fp);
return xlsArea;
}
}
最後把官方的jxlsHelper更換為自定義的CusJxlsHelper,ok,工作正常。 最終程式碼如下:
@RequestMapping(value = WmsUrlConstants.Shipment.RED_DOWNLOAD_SHIPPING_DATA_LIST, method = RequestMethod.GET)
public ResponseEntity<byte[]> downloadShippingDataList(@PathVariable("shipmentId") @NotNull Long shipmentId) {
String filename = "xxxxxxx.xlsx";
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
int listCount = shipmentDownloadService.getShippingDataCountByred(shipmentId);
ComStoreModel store = ComStore.getStoreById(getSelStoreId());
String downloadFileName = WmsConstant.ShippingDataList.FILE_NAME + store.getStoreName()
+ "_ShippingData_" + sdf.format(new Date()) + "-" + listCount + "件.zip";
List<ShipmentDisShippingDataListBean> shippingDataList =
shipmentDownloadService.getShippingDataListBeans(shipmentId);
ExcelZipBuilder zipBuilder = new ExcelZipBuilder();
//獲取模板檔案
Path defaultFile = EnvUtils.isDevFromSystem() ?
Paths.get(Objects.requireNonNull(this.getClass().getClassLoader().getResource(
WmsConstant.WMS_TEMPLATE_ROOT + filename)).getPath().replaceFirst("^/(.:/)", "$1")) :
WmsPathUtil.getTemplateReportPath().resolve(filename);
for (xxxxx x : xxxxxxxList) {
Context context = new Context();
//業務程式碼
zipBuilder.addEntry(context, defaultFile.toFile(), channelName + ".xlsx");
}
byte[] result = zipBuilder.build();
return genResponseEntityFromBytes(MediaType.APPLICATION_OCTET_STREAM,
downloadFileName, result);
} catch (Exception e) {
throw new CodeException(CodeConstant.Common.DOWNLOAD_FILE_ERROR, e);
}
}
ExcelZipBuilder 程式碼如下
package com.voyageone.ecerp.web.wms.helper;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* Created with IntelliJ IDEA.
*
* @author: jet.xie
* @Date: 2018/9/13
* @Time: 15:19
* @Description:
* @version: 1.0.0
*/
public class ExcelZipBuilder {
private static Logger logger = LoggerFactory.getLogger(WmsJxlsHelper.class);
private List<Entry> entries = new ArrayList<>();
public ExcelZipBuilder addEntry(Context context, File templateFile, String targetFileName) {
entries.add(new Entry(context, targetFileName, templateFile, true));
return this;
}
public ExcelZipBuilder addEntry(Context context, File templateFile, String targetFileName, boolean isDeleteTemplateSheet) {
entries.add(new Entry(context, targetFileName, templateFile, isDeleteTemplateSheet));
return this;
}
public byte[] build() throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(bos)
) {
logger.info("====================壓縮{}份檔案", entries.size());
for (Entry entry : entries) {
ZipEntry zipEntry = new ZipEntry(entry.entryName);
zos.putNextEntry(zipEntry);
byte[] bytes = entry.toByte();
zos.write(bytes);
zos.closeEntry();
}
zos.close();
return bos.toByteArray();
}
}
private static class Entry {
/**
* 填充內容
*/
private Context context;
/**
* excel檔名稱
*/
private String entryName;
/**
* 模板名稱
*/
private File templateFile;
/**
* 是否刪除templateSheet
*/
private boolean isDeleteTemplateSheet;
Entry(Context context, String entryName, File templateFile, boolean isDeleteTemplateSheet) {
this.context = context;
this.entryName = entryName;
this.templateFile = templateFile;
this.isDeleteTemplateSheet = isDeleteTemplateSheet;
}
byte[] toByte() throws IOException {
//讀取檔案流
FileInputStream input = new FileInputStream(templateFile);
ByteArrayOutputStream output = new ByteArrayOutputStream();
//用jxlsHelper來處理xlxs輸出了流
JxlsHelper jxlsHelper = new WmsJxlsHelper();
jxlsHelper.setDeleteTemplateSheet(isDeleteTemplateSheet);
jxlsHelper.processTemplate(input, output, context);
return output.toByteArray();
}
public boolean isDeleteTemplateSheet() {
return isDeleteTemplateSheet;
}
public void setDeleteTemplateSheet(boolean deleteTemplateSheet) {
isDeleteTemplateSheet = deleteTemplateSheet;
}
}
}