剛做完項目稍微總結一下。
我們遇到一個功能的時候常常面臨選擇技術,選不好就掉到坑裏面去了就特麼折騰半天不滿足要求所以很難受,所以對於自己重新接觸的技術真的要了解全面了之後再下手,我寫這個文章是來告訴大家我項目中用到的技術
word導出使用freemarker 模板
優點:滿足所有可能的需求
缺點:導出的其實是xml文件而已,只是word高版本支持xml類型的word ,手機是無法打開的,打開就是xml文件。解決辦法網上有一堆,安裝office 使用jacob的jar包加上jacob-1.19-x64.dll文件來調用windows的office轉換成真的word(效率慢的一批),如果哪位大哥知道怎麼解決麻煩告知一下啊。
還有坑巨多,freemarker的語法賊坑,沒有數據就報錯,然後就是你得把word先整理成xml數據(基本上網上的教程不靠譜,你得自己去摸索這個xml的含義)
綜上如果是linux系統部署那你最好還是老老實實用poi吧。
代碼:網上一堆,看不懂那你基本告別這個行業了。
效果:
自己上網去查查這個文檔多複雜,單選,多選,圖片,分頁,頁眉,頁腳(這個是word自帶的功能),都可以滿足你的需求。(就是這個模板你自己得好好看看)
excel導出用jxls模板技術
優點:快,爽
缺點:暫時沒發現,反正比poi爽多了
我以前也一直用poi導出excel,調整間距,excel導出不好看各種麻煩事,直到我發現jxls模板一切變得簡單起來。技術很簡單,幾乎可以滿足你所有excel的需求,所以不要怕大膽用。
貼一個官網http://jxls.sourceforge.net/samples/object_collection_xmlbuilder.html
導入導出我都寫了,導入還是用的poi我覺得導入還是很簡單的。我稍微封裝了一下,代碼貼一下。部分業務代碼不貼。
說一下代碼思路:讀取字段屬性,反射設置對象值,並判斷是否爲字典數據,字典數據通過註解判斷,自己在類上面寫個註解,字典數據替換完事。
jar包貼一下,注意版本,低版本有坑。
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls-poi</artifactId>
<version>1.0.16</version>
</dependency>
package com.wenbao.vitwbcrm.utility;
import com.ruoyi.common.config.Global;
import com.wenbao.vitwbcrm.aop.annotation.PoiImportData;
import com.wenbao.vitwbcrm.bkydww.mapper.BaseToolMapper;
import com.wenbao.vitwbcrm.bwg.entity.BaseRelic;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
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.ss.usermodel.CellType;
import org.jxls.common.Context;
import org.jxls.transform.Transformer;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.JxlsHelper;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Jxls 模板導入導出
* Created by jhwang
* Date 2019/3/25 15:54
*/
public class JxlsUtils {
/**
* xml文件名稱
*/
private String xmlName;
/**
* xml文件地址
*/
private String xmlPath;
/**
* 數據所在行
*/
private Integer rowNumber;
/**
* 數據所在工作表
*/
private Integer sheetNumber = 0;
/**
* 設置是否生成主鍵,默認true
*/
private boolean ifcreateId = true;
/**
* 主鍵默認字段
*/
private String id = "id";
public BaseToolMapper baseToolMapper;
public JxlsUtils() {}
/**
* @param xmlName 模板名稱
* @param rowNumber 對應數據開始行
*/
public JxlsUtils(String xmlName,Integer rowNumber) {
this.xmlName = xmlName;
this.rowNumber = rowNumber;
//獲取默認文件夾下的文件
this.xmlPath = FileUtils.getPath("jxlsxml"+"/"+xmlName.replace(File.separator,""));
}
/**
* 讀取office表格中的數據
* @param xmlName 模板名稱
* @return
*/
private static Object readOfficeDataStatic(String xmlName, String tableName,Integer rowNumber,Class cls, InputStream inp){
JxlsUtils jxlsUtils = new JxlsUtils(xmlName,tableName,rowNumber);
return jxlsUtils.readPoiOfficeData(cls,inp);
}
/**
* 基於poi讀取office表格中的數據
* @param inputStream 讀取的文件流數據,
* @return
*/
public Object readPoiOfficeData(Class cls,InputStream inputStream){
List<Object> list = new ArrayList<Object>();
//獲取所有的字段
Map xmlMap = getXmlMap();
HSSFWorkbook workbook = null;
try {
workbook = new HSSFWorkbook(inputStream);
HSSFSheet hssfSheet = workbook.getSheetAt(this.sheetNumber);
//循環行
for (int rowNum = this.rowNumber; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
HSSFRow hssfRow = hssfSheet.getRow(rowNum);
if (hssfRow == null ) {
continue;
}
Object o = cls.newInstance();
for (int rowi = 0; rowi <= hssfRow.getLastCellNum(); rowi++) {
HSSFCell cell = hssfRow.getCell(rowi);
if (cell == null) {
continue;
}
//讀取數據前設置單元格類型
cell.setCellType(CellType.STRING);
String value = cell.getStringCellValue();
if(xmlMap.get(rowi) != null){
BeanUtils.setProperty(o, (String) xmlMap.get(rowi), value);
}
}
//如果爲null則結束循環
if(ifBenanNull(o)){
return list;
}
//是否生成主鍵
if(ifcreateId){
BeanUtils.setProperty(o, this.id, Uuid.AddUUid());
}
list.add(o);
}
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return list;
}
/**
* 基於jxls模板導出數據
* @param list 導出數據集合
* @return
*/
public String exportExcel(List list) throws IOException {
//模板遍歷對象
String examList = "examList";
//文件臨時存放地址
String fileName = DateUtils.getYYYYMMDD()+".xlsx";
File out = new File( Global.getDownloadPath()+fileName);
Context context = PoiTransformer.createInitialContext();
context.putVar(examList, list);
JxlsHelper jxlsHelper = JxlsHelper.getInstance();
Transformer transformer = jxlsHelper.createTransformer(new FileInputStream(this.xmlPath), new FileOutputStream(out));
jxlsHelper.processTemplate(context, transformer);
return fileName;
}
/**
* 基於jxls模板導出數據 橫向數據導出
* @param rowlist 橫向數據
* @param datalist 集合數據
* @return
*/
public String exportExcelRow(List rowlist,List datalist) throws IOException {
// try(InputStream is = GridCommandDemo.class.getResourceAsStream("grid_template.xls")) {
// try(OutputStream os = new FileOutputStream("target/grid_output2.xls")) {
// Context context = new Context();
// context.putVar("rowlist", Arrays.asList("Name", "Birthday", "Payment"));
// context.putVar("datalist", employees);
// JxlsHelper.getInstance().processGridTemplateAtCell(is, os, context, "name,birthDate,payment", "Sheet2!A1");
// }
// }
return null;
}
/**
* 判斷對象是否全部爲null 或者“”,如果是返回true 否返回false
* @param obj
* @return
* @throws IllegalAccessException
*/
private boolean ifBenanNull(Object obj) {
boolean flag = true;
Field[] declaredFields = obj.getClass().getDeclaredFields();
for(Field f : declaredFields){
f.setAccessible(true);
try {
if("serialVersionUID".equals(f.getName())){
continue;
}
if(BeanUtils.getProperty(obj,f.getName()) != null && !"".equals(BeanUtils.getProperty(obj,f.getName()))){
return false;
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
return flag;
}
/**
* 獲取xml文件中所設置的字段返回map
* key - 字段名稱
* value - 字段所屬位置
*/
private Map getXmlMap(){
Map<Integer, String> map = new HashMap<>();
HSSFWorkbook workbook = null;
try {
// 讀取Excel文件
FileInputStream fileInputStream = new FileInputStream(this.xmlPath);
workbook = new HSSFWorkbook(fileInputStream);
HSSFSheet hssfSheet = workbook.getSheetAt(this.sheetNumber);
HSSFRow row = hssfSheet.getRow(this.rowNumber);
// 循環列
for (int rowNum = 0; rowNum <= row.getLastCellNum(); rowNum++) {
HSSFCell cell = row.getCell(rowNum);
if (cell == null) {
continue;
}
cell.setCellType(CellType.STRING);
if(cell.getStringCellValue() != null && !"".equals(cell.getStringCellValue())){
String value = formatParamCode(cell.getStringCellValue()).split("\\.")[1];
if(value!=null && !"".equals(value)){
map.put(rowNum,value);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
/**
* 取出${}中的數據
* @param paramCode
* @return
*/
public String formatParamCode(String paramCode){
return paramCode.replaceAll("\\$", "").replaceAll("\\{", "").replaceAll("\\}", "");
}
/**
* 根據導出對象上的註解 PoiImportData 設置轉換成對應的字典數據
*/
public void processingCodeData(List list, BaseToolMapper baseToolMapper) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
for (Object obj:list) {
Map<String, Object> describe = PropertyUtils.describe(obj);
for (String key : describe.keySet()) {
//排除掉默認的class
if(key.equals("class")){
continue;
}
if(describe.get(key) != null && !describe.get(key).toString().trim().equals("")){
//獲取註解
PoiImportData annotation = obj.getClass().getDeclaredField(key).getAnnotation(PoiImportData.class);
if(annotation != null){
//表名
String tableName = annotation.tableName();
//主鍵
String id = annotation.id();
//value、
String value = annotation.value();
String s = baseToolMapper.selectCodeID(tableName, id, value, (String) describe.get(key));
BeanUtils.setProperty(obj,key,s);
}
}
}
}
}
public static void main(String[] ags) throws IllegalAccessException, Exception {
JxlsUtils jxlsUtils = new JxlsUtils("可移動文物標準模板.xls", 3);
try {
FileInputStream fileInputStream = new FileInputStream("D:\\青海項目\\各市州一普資料\\63232441900003河南蒙古族自治縣拉卡寺.xls");
//導入
List<BaseRelic> list = (List<BaseRelic>)jxlsUtils.readPoiOfficeData(BaseRelic.class, fileInputStream);
//導出
jxlsUtils.exportExcel(list);
} catch (Exception e) {
e.printStackTrace();
}
// JxlsUtils jxlsUtils = new JxlsUtils();
// BaseRelic baseRelic = new BaseRelic();
// //baseRelic.setgId("11");
// boolean b = jxlsUtils.ifBenanNull(baseRelic);
// System.out.println(b);
}
}