package com.wanju.project001.zonghe.common.controller;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.wanju.project001.zonghe.handler.EIEntity;
import com.wanju.project001.zonghe.handler.ScanPojoHandler;
@Controller
@RequestMapping("/extro")
public class ExtroFuncIndexExportImportController {
@Autowired
ScanPojoHandler scanPojoHandler;
@RequestMapping("/init")
public ModelAndView index(HttpServletRequest request,
HttpServletResponse response) {
ModelAndView view = new ModelAndView("/extro/extro");
return view;
}
@RequestMapping("/import")
public ModelAndView importFile(HttpServletRequest request,
HttpServletResponse response) {
String path = request.getParameterMap().get("filepath")[0];
if (null != path && !"".equals(path)) {
}
return null;
}
@RequestMapping("/export")
public ModelAndView export(HttpServletRequest request,
HttpServletResponse response) {
ModelAndView view = new ModelAndView("/extro/test");
String tabname = request.getParameterMap().get("tabname")[0];
System.out.println("comon");
if ("user".equals(tabname)) {
// 第一步,建立一個webbook,對應一個Excel檔案
HSSFWorkbook wb = new HSSFWorkbook();
// 第二步,在webbook中新增一個sheet,對應Excel檔案中的sheet
HSSFSheet sheet = wb.createSheet("學生表一");
// 第三步,在sheet中新增表頭第0行,注意老版本poi對Excel的行數列數有限制short
HSSFRow row = sheet.createRow((int) 0);
// 第四步,建立單元格,並設定值表頭 設定表頭居中
HSSFCellStyle style = wb.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 建立一個居中格式
HSSFCell cell = row.createCell((short) 0);
cell.setCellValue("id");
cell.setCellStyle(style);
cell = row.createCell((short) 1);
cell.setCellValue("name");
cell.setCellStyle(style);
cell = row.createCell((short) 2);
cell.setCellValue("password");
cell.setCellStyle(style);
// 第五步,寫入實體資料 實際應用中這些資料從資料庫得到,
for (int i = 0; i < users.length; i++) {
row = sheet.createRow((int) i + 1);
row.createCell((short) 0).setCellValue(users[i].getId());
row.createCell((short) 1).setCellValue(users[i].getName());
row.createCell((short) 2).setCellValue(users[i].getPassword());
}
// 第六步,將檔案存到指定位置
try {
FileOutputStream fout = new FileOutputStream("D:/students.xls");
wb.write(fout);
fout.close();
} catch (Exception e) {
e.printStackTrace();
}
PrintWriter writer;
try {
writer = response.getWriter();
writer.println("資料已經匯入完畢,匯入了" + users.length + "條資料");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
@RequestMapping("/exportreflect")
public ModelAndView exportReflect(HttpServletRequest request,
HttpServletResponse response) {
ModelAndView view = new ModelAndView("/extro/test");
String tabname = request.getParameterMap().get("tabname")[0];
System.out.println("comon");
Set<Class<?>> sets= scanPojoHandler.execute();
if ("user".equals(tabname)) {
// 第一步,建立一個webbook,對應一個Excel檔案
HSSFWorkbook wb = new HSSFWorkbook();
// 第二步,在webbook中新增一個sheet,對應Excel檔案中的sheet
HSSFSheet sheet = wb.createSheet("學生表一");
// 第三步,在sheet中新增表頭第0行,注意老版本poi對Excel的行數列數有限制short
HSSFRow row = sheet.createRow((int) 0);
// 第四步,建立單元格,並設定值表頭 設定表頭居中
HSSFCellStyle style = wb.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 建立一個居中格式
// 第五步,寫入實體資料 實際應用中這些資料從資料庫得到,
for (int i = 0; i < users.length; i++) {
HSSFCell cell = row.createCell(0);
if (i == 0) {
addCellForTitle(
row,
users[i],
"com.wanju.project001.zonghe.common.controller.User",
style);
}
row = sheet.createRow((int) i + 1);
if (users[i] instanceof User)
addCell(row, users[i],
"com.wanju.project001.zonghe.common.controller.User");
else {
System.out.println("判斷其他型別");
}
}
// 第六步,將檔案存到指定位置
try {
FileOutputStream fout = new FileOutputStream(
"D:/studentsreflect.xls");
wb.write(fout);
fout.close();
} catch (Exception e) {
e.printStackTrace();
}
PrintWriter writer;
try {
writer = response.getWriter();
writer.println("資料已經匯入完畢,匯入了" + users.length + "條資料");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
@RequestMapping("/exportreflectanno")
public ModelAndView exportReflectanno(HttpServletRequest request,
HttpServletResponse response) {
ModelAndView view = new ModelAndView("/extro/test");
String tabname = request.getParameterMap().get("tabname")[0];
System.out.println("comon");
// Set<Class<?>> sets= scanPojoHandler.execute();
Set<Class> sets= scanPojoHandler.executeFix();
if ("user".equals(tabname)) {
// 第一步,建立一個webbook,對應一個Excel檔案
HSSFWorkbook wb = new HSSFWorkbook();
// 第二步,在webbook中新增一個sheet,對應Excel檔案中的sheet
HSSFSheet sheet = wb.createSheet("學生表一");
// 第三步,在sheet中新增表頭第0行,注意老版本poi對Excel的行數列數有限制short
HSSFRow row = sheet.createRow((int) 0);
// 第四步,建立單元格,並設定值表頭 設定表頭居中
HSSFCellStyle style = wb.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 建立一個居中格式
// 第五步,寫入實體資料 實際應用中這些資料從資料庫得到,
for (int i = 0; i < users.length; i++) {
HSSFCell cell = row.createCell(0);
if (i == 0) {
for (Iterator iterator = sets.iterator(); iterator
.hasNext();) {
Class class1 = (Class) iterator.next();
Object obj = null;
try {
obj = class1.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// if(users[i]instanceof class1.newInstance().getClass()){
if(users[i].getClass().isInstance(obj)){
System.out.println("flg"+class1.getPackage()+class1.getName());
addCellForTitle(
row,
users[i],
class1.getName(),
style);
}
}
}
row = sheet.createRow((int) i + 1);
if (users[i] instanceof User)
addCell(row, users[i],
"com.wanju.project001.zonghe.common.controller.User");
else {
System.out.println("判斷其他型別");
}
}
// 第六步,將檔案存到指定位置
try {
FileOutputStream fout = new FileOutputStream(
"D:/studentsreflect.xls");
wb.write(fout);
fout.close();
} catch (Exception e) {
e.printStackTrace();
}
PrintWriter writer;
try {
writer = response.getWriter();
writer.println("資料已經匯入完畢,匯入了" + users.length + "條資料");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
public static final User[] users = { new User(1, "33", "991"),
new User(2, "34", "992"), new User(3, "35", "993") };
public void addCellForTitle(HSSFRow row, Object object, String objectPath,
HSSFCellStyle style) {
Class class1;
try {
class1 = Class.forName(objectPath);
// Object object = class1.newInstance();
// Method[] methods = class1.getMethods();
Field[] fields = class1.getDeclaredFields();
class1.getFields();
for (int i = 0; i < fields.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellStyle(style);
System.out.println(fields[i].getName());
cell.setCellValue(fields[i].getName().toString());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void addCell(HSSFRow row, Object object, String objectPath) {
Class class1;
try {
class1 = Class.forName(objectPath);
// Object object = class1.newInstance();
Method[] methods = class1.getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().contains("get")
&& !methods[i].getName().equals("getClass")) {
Object result = methods[i].invoke(object);
row.createCell(i).setCellValue(result.toString());
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@EIEntity
class User {
private int id;
private String name;
private String password;
public User() {
// TODO Auto-generated constructor stub
}
public User(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package com.wanju.project001.zonghe.handler;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class ScanPojoHandler {
private String basePojoPackage;
public Set<Class<?>> execute() {
System.out.println("basePojoPackage" + basePojoPackage);
return getClasses(basePojoPackage);
}
public Set<Class> executeFix() {
System.out.println("basePojoPackage" + basePojoPackage);
return getClassesFix(basePojoPackage);
}
public String getBasePojoPackage() {
return basePojoPackage;
}
public void setBasePojoPackage(String basePojoPackage) {
this.basePojoPackage = basePojoPackage;
}
public static Set<Class<?>> getClasses(String pack) {
// 第一個class類的集合
Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
// 是否迴圈迭代
boolean recursive = true;
// 獲取包的名字 並進行替換
String packageName = pack;
String packageDirName = packageName.replace('.', '/');
// 定義一個列舉的集合 並進行迴圈來處理這個目錄下的things
Enumeration<URL> dirs;
try {
dirs = Thread.currentThread().getContextClassLoader()
.getResources(packageDirName);
// 迴圈迭代下去
while (dirs.hasMoreElements()) {
// 獲取下一個元素
URL url = dirs.nextElement();
// 得到協議的名稱
String protocol = url.getProtocol();
// 如果是以檔案的形式儲存在伺服器上
if ("file".equals(protocol)) {
System.err.println("file型別的掃描");
// 獲取包的物理路徑
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
// 以檔案的方式掃描整個包下的檔案 並新增到集合中
findAndAddClassesInPackageByFile(packageName, filePath,
recursive, classes);
} else if ("jar".equals(protocol)) {
// 如果是jar包檔案
// 定義一個JarFile
System.err.println("jar型別的掃描");
JarFile jar;
try {
// 獲取jar
jar = ((JarURLConnection) url.openConnection())
.getJarFile();
// 從此jar包 得到一個列舉類
Enumeration<JarEntry> entries = jar.entries();
// 同樣的進行迴圈迭代
while (entries.hasMoreElements()) {
// 獲取jar裡的一個實體 可以是目錄 和一些jar包裡的其他檔案 如META-INF等檔案
JarEntry entry = entries.nextElement();
String name = entry.getName();
// 如果是以/開頭的
if (name.charAt(0) == '/') {
// 獲取後面的字串
name = name.substring(1);
}
// 如果前半部分和定義的包名相同
if (name.startsWith(packageDirName)) {
int idx = name.lastIndexOf('/');
// 如果以"/"結尾 是一個包
if (idx != -1) {
// 獲取包名 把"/"替換成"."
packageName = name.substring(0, idx)
.replace('/', '.');
}
// 如果可以迭代下去 並且是一個包
if ((idx != -1) || recursive) {
// 如果是一個.class檔案 而且不是目錄
if (name.endsWith(".class")
&& !entry.isDirectory()) {
// 去掉後面的".class" 獲取真正的類名
String className = name.substring(
packageName.length() + 1,
name.length() - 6);
try {
// 新增到classes
classes.add(Class
.forName(packageName + '.'
+ className));
} catch (ClassNotFoundException e) {
// log
// .error("新增使用者自定義檢視類錯誤 找不到此類的.class檔案");
e.printStackTrace();
}
}
}
}
}
} catch (IOException e) {
// log.error("在掃描使用者定義檢視時從jar包獲取檔案出錯");
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return classes;
}
public static Set<Class> getClassesFix(String pack) {
// 第一個class類的集合
Set<Class> classes = new LinkedHashSet<Class>();
// 是否迴圈迭代
boolean recursive = true;
// 獲取包的名字 並進行替換
String packageName = pack;
String packageDirName = packageName.replace('.', '/');
// 定義一個列舉的集合 並進行迴圈來處理這個目錄下的things
Enumeration<URL> dirs;
try {
dirs = Thread.currentThread().getContextClassLoader()
.getResources(packageDirName);
// 迴圈迭代下去
while (dirs.hasMoreElements()) {
// 獲取下一個元素
URL url = dirs.nextElement();
// 得到協議的名稱
String protocol = url.getProtocol();
// 如果是以檔案的形式儲存在伺服器上
if ("file".equals(protocol)) {
System.err.println("file型別的掃描");
// 獲取包的物理路徑
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
// 以檔案的方式掃描整個包下的檔案 並新增到集合中
findAndAddClassesInPackageByFileFix(packageName, filePath,
recursive, classes);
} else if ("jar".equals(protocol)) {
// 如果是jar包檔案
// 定義一個JarFile
System.err.println("jar型別的掃描");
JarFile jar;
try {
// 獲取jar
jar = ((JarURLConnection) url.openConnection())
.getJarFile();
// 從此jar包 得到一個列舉類
Enumeration<JarEntry> entries = jar.entries();
// 同樣的進行迴圈迭代
while (entries.hasMoreElements()) {
// 獲取jar裡的一個實體 可以是目錄 和一些jar包裡的其他檔案 如META-INF等檔案
JarEntry entry = entries.nextElement();
String name = entry.getName();
// 如果是以/開頭的
if (name.charAt(0) == '/') {
// 獲取後面的字串
name = name.substring(1);
}
// 如果前半部分和定義的包名相同
if (name.startsWith(packageDirName)) {
int idx = name.lastIndexOf('/');
// 如果以"/"結尾 是一個包
if (idx != -1) {
// 獲取包名 把"/"替換成"."
packageName = name.substring(0, idx)
.replace('/', '.');
}
// 如果可以迭代下去 並且是一個包
if ((idx != -1) || recursive) {
// 如果是一個.class檔案 而且不是目錄
if (name.endsWith(".class")
&& !entry.isDirectory()) {
// 去掉後面的".class" 獲取真正的類名
String className = name.substring(
packageName.length() + 1,
name.length() - 6);
try {
// 新增到classes
classes.add(Class
.forName(packageName + '.'
+ className));
} catch (ClassNotFoundException e) {
// log
// .error("新增使用者自定義檢視類錯誤 找不到此類的.class檔案");
e.printStackTrace();
}
}
}
}
}
} catch (IOException e) {
// log.error("在掃描使用者定義檢視時從jar包獲取檔案出錯");
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return classes;
}
/**
* 以檔案的形式來獲取包下的所有Class
*
* @param packageName
* @param packagePath
* @param recursive
* @param classes
*/
public static void findAndAddClassesInPackageByFile(String packageName,
String packagePath, final boolean recursive, Set<Class<?>> classes) {
// 獲取此包的目錄 建立一個File
File dir = new File(packagePath);
// 如果不存在或者 也不是目錄就直接返回
if (!dir.exists() || !dir.isDirectory()) {
// log.warn("使用者定義包名 " + packageName + " 下沒有任何檔案");
return;
}
// 如果存在 就獲取包下的所有檔案 包括目錄
File[] dirfiles = dir.listFiles(new FileFilter() {
// 自定義過濾規則 如果可以迴圈(包含子目錄) 或則是以.class結尾的檔案(編譯好的java類檔案)
public boolean accept(File file) {
return (recursive && file.isDirectory())
|| (file.getName().endsWith(".class"));
}
});
// 迴圈所有檔案
for (File file : dirfiles) {
// 如果是目錄 則繼續掃描
if (file.isDirectory()) {
findAndAddClassesInPackageByFile(
packageName + "." + file.getName(),
file.getAbsolutePath(), recursive, classes);
} else {
// 如果是java類檔案 去掉後面的.class 只留下類名
String className = file.getName().substring(0,
file.getName().length() - 6);
try {
// 新增到集合中去
// classes.add(Class.forName(packageName + '.' +
// className));
// 經過回覆同學的提醒,這裡用forName有一些不好,會觸發static方法,沒有使用classLoader的load乾淨
classes.add(Thread.currentThread().getContextClassLoader()
.loadClass(packageName + '.' + className));
} catch (ClassNotFoundException e) {
// log.error("新增使用者自定義檢視類錯誤 找不到此類的.class檔案");
e.printStackTrace();
}
}
}
}
public static void findAndAddClassesInPackageByFileFix(String packageName,
String packagePath, final boolean recursive, Set<Class> classes) {
// 獲取此包的目錄 建立一個File
File dir = new File(packagePath);
// 如果不存在或者 也不是目錄就直接返回
if (!dir.exists() || !dir.isDirectory()) {
// log.warn("使用者定義包名 " + packageName + " 下沒有任何檔案");
return;
}
// 如果存在 就獲取包下的所有檔案 包括目錄
File[] dirfiles = dir.listFiles(new FileFilter() {
// 自定義過濾規則 如果可以迴圈(包含子目錄) 或則是以.class結尾的檔案(編譯好的java類檔案)
public boolean accept(File file) {
return (recursive && file.isDirectory())
|| (file.getName().endsWith(".class"));
}
});
// 迴圈所有檔案
for (File file : dirfiles) {
// 如果是目錄 則繼續掃描
if (file.isDirectory()) {
findAndAddClassesInPackageByFileFix(
packageName + "." + file.getName(),
file.getAbsolutePath(), recursive, classes);
} else {
// 如果是java類檔案 去掉後面的.class 只留下類名
String className = file.getName().substring(0,
file.getName().length() - 6);
try {
// 新增到集合中去
// classes.add(Class.forName(packageName + '.' +
// className));
// 經過回覆同學的提醒,這裡用forName有一些不好,會觸發static方法,沒有使用classLoader的load乾淨
Class clz = Thread.currentThread().getContextClassLoader()
.loadClass(packageName + '.' + className);
EIEntity iEiEntity = (EIEntity) clz
.getAnnotation(EIEntity.class);
if (iEiEntity != null) {
classes.add(Thread.currentThread()
.getContextClassLoader()
.loadClass(packageName + '.' + className));
} else {
System.out.println("非pojo類");
}
} catch (ClassNotFoundException e) {
// log.error("新增使用者自定義檢視類錯誤 找不到此類的.class檔案");
e.printStackTrace();
}
}
}
}
}