Excelレポートの自動化
7086 ワード
仕事ではdailyのレポートがよくありますが、毎回フォーマットが同じで、ソースも基本的にデータベースのテーブルで、毎回自分で貼り付けるのは面倒です.
pythonやsasなどのツールやパッケージを試したことがありますが、pythonのxlrdなどのシリーズは07以降のexcelファイルをサポートしていません.openpyxlはデータを置き換えた後、cellのフォーマットを失いやすく、sasは1位が有料で、2位も03バージョンのexcelのみをサポートしています.幸いpoiで処理できます.
本編では主にいくつかの関数と処理の考え方だけを記録し、デフォルトではSpring+Mybatisの組み合わせが完成しています.
まずmaybatisを使用するとORMを無視できます.長い間同じsqlで対応するオブジェクトを与えるのはまあまあですが、頻繁にフィールドが変動してしまうと面倒なので、mybatisはクエリ結果をHashMapに戻すことができるので、LinkedHashMapをそのまま使います.
上記の関数は、mabatisを介して返されたmapオブジェクトにクエリーされたと仮定します.呼び出し後、新しいSXSSFWORkBookオブジェクトを直接得ることができます.これはpoiで大きなデータをエクスポートするためのオブジェクトです.受信も簡単です.mainではnew XSSFWORkBookを受信すればいいです.
これはテンプレート内のsheetを置き換えるために使用されます.レポートの形式が変わらない可能性があるため、後ろに隠されているsheetは前にマッピングされたデータとして使用されます(表示されているsheetはすべて数式で、実際のデータは後ろのhideのsheetの中にあります).開始行選択1は全sheet置換、選択2は2行目から置換を削除します.ここでstyleスタイルの問題があります.テンプレートを使用する場合、第1動作フィールドの名前、第2動作サンプルのデータをお勧めします.返されるオブジェクトは同じようにXSSFWORkbookで受信します.
最後にデータがリフレッシュされた後にリフレッシュする必要があるのは式です.poiは自動的にデータを生成した後、excelを開くと、式としての数値が自分でリフレッシュされないことがわかりやすいので、式をリフレッシュする関数もあります.
XSSFWORkbookオブジェクトを入力します.
最後の質問ですが、ORMのマッピングが事前に完了している場合は、新しい方法を書くのではなく、HashMapに戻る一般的な方法を呼び出したい場合は、オブジェクトをMapに変換します.
関数を参照してください.
また、複数のsheetを置き換え、removeRowを使用すると空のポインタ異常が発生します.Rowのストレージはスレッド外で安全なTreeMapですが、削除操作には影響しませんので、この状況をスキップしただけです.具体的な原理がわかったら教えてください.
フォーマット処理の要求があれば、この文章を参考にしてください.
クリックしてリンクを開く
pythonやsasなどのツールやパッケージを試したことがありますが、pythonのxlrdなどのシリーズは07以降のexcelファイルをサポートしていません.openpyxlはデータを置き換えた後、cellのフォーマットを失いやすく、sasは1位が有料で、2位も03バージョンのexcelのみをサポートしています.幸いpoiで処理できます.
本編では主にいくつかの関数と処理の考え方だけを記録し、デフォルトではSpring+Mybatisの組み合わせが完成しています.
まずmaybatisを使用するとORMを無視できます.長い間同じsqlで対応するオブジェクトを与えるのはまあまあですが、頻繁にフィールドが変動してしまうと面倒なので、mybatisはクエリ結果をHashMapに戻すことができるので、LinkedHashMapをそのまま使います.
// ,
public static SXSSFWorkbook createWorkbookWithoutBean2(List> list, Object adb){
SXSSFWorkbook workbook = new SXSSFWorkbook(1000);
SXSSFSheet sheet = workbook.createSheet("sheet");
SXSSFRow row = sheet.createRow(0); // bean
SXSSFCell cell = row.createCell(0);
cell.setCellValue(adb.toString());
row = sheet.createRow(1);
if(list.size()!=0)
try {
// key ArrayList
LinkedHashMap map = list.get(0); // map, key
Set keySet = map.keySet();
Iterator iterator = keySet.iterator();
ArrayList keys = new ArrayList();
while(iterator.hasNext()){
keys.add(iterator.next());
}
//
for(int i=0; i> iter1 = list.iterator();
while(iter1.hasNext()){
row = sheet.createRow(rowIndex++);
map = iter1.next();
for(int i=0; i
上記の関数は、mabatisを介して返されたmapオブジェクトにクエリーされたと仮定します.呼び出し後、新しいSXSSFWORkBookオブジェクトを直接得ることができます.これはpoiで大きなデータをエクスポートするためのオブジェクトです.受信も簡単です.mainではnew XSSFWORkBookを受信すればいいです.
/**
*
* @param wb
* @param sheetName
* @param sql sql, sql mapper.xml id
* @param start_line excel ,
* @param sqlParam Object , mapper.xml
* @return
*/
public static synchronized XSSFWorkbook replaceSheet(XSSFWorkbook wb, String sheetName, String sql, int start_line, String sqlParam){
try {
XSSFSheet sheet = wb.getSheet(sheetName);
int lastRow = sheet.getLastRowNum();
XSSFRow row;
XSSFCell cell;
XSSFCellStyle style = wb.createCellStyle();
row = sheet.getRow(start_line-1);
int rowIndex = start_line-1;
if(row.getCell(0)!=null){
style = row.getCell(0).getCellStyle();
}else{
style.setBorderBottom(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
}
for(int i=start_line-1; i<=lastRow; i++){
row = sheet.getRow(i);
if(row!=null){
myRemoveRow(sheet, row);
}
}//
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
System.out.println(sql);
System.out.println(sqlParam);
List> list = session.selectList(sql, sqlParam);
System.out.println(list.size());
if(list.size()!=0){
LinkedHashMap map = list.get(0);
Set keySet = map.keySet();
Iterator iterator = keySet.iterator();
ArrayList keys = new ArrayList();
while(iterator.hasNext()){
keys.add(iterator.next());
}
//
Iterator> iter1 = list.iterator();
while(iter1.hasNext()){
row = sheet.createRow(rowIndex++);
map = iter1.next();
for(int i=0; i
これはテンプレート内のsheetを置き換えるために使用されます.レポートの形式が変わらない可能性があるため、後ろに隠されているsheetは前にマッピングされたデータとして使用されます(表示されているsheetはすべて数式で、実際のデータは後ろのhideのsheetの中にあります).開始行選択1は全sheet置換、選択2は2行目から置換を削除します.ここでstyleスタイルの問題があります.テンプレートを使用する場合、第1動作フィールドの名前、第2動作サンプルのデータをお勧めします.返されるオブジェクトは同じようにXSSFWORkbookで受信します.
最後にデータがリフレッシュされた後にリフレッシュする必要があるのは式です.poiは自動的にデータを生成した後、excelを開くと、式としての数値が自分でリフレッシュされないことがわかりやすいので、式をリフレッシュする関数もあります.
public static void updateFormula(Workbook wb){
for(int sheet_index=0;sheet_index
XSSFWORkbookオブジェクトを入力します.
最後の質問ですが、ORMのマッピングが事前に完了している場合は、新しい方法を書くのではなく、HashMapに戻る一般的な方法を呼び出したい場合は、オブジェクトをMapに変換します.
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;
public class BeanMapTrans {
public static LinkedHashMap transBean2Map(Object obj){
if(obj == null){
return null;
}
LinkedHashMap map = new LinkedHashMap();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
// class
if (!key.equals("class")) {
// property getter
Method getter = property.getReadMethod();
Object value = getter.invoke(obj);
map.put(key, value);
}
}
} catch (Exception e) {
System.out.println("transBean2Map Error " + e);
}
return map;
}
}
関数を参照してください.
また、複数のsheetを置き換え、removeRowを使用すると空のポインタ異常が発生します.Rowのストレージはスレッド外で安全なTreeMapですが、削除操作には影響しませんので、この状況をスキップしただけです.具体的な原理がわかったら教えてください.
フォーマット処理の要求があれば、この文章を参考にしてください.
クリックしてリンクを開く