teddyhuang 5 лет назад
Родитель
Сommit
f8832d3faa
10 измененных файлов: 760 добавлений и 262 удалений
  1. +23
    -12
      app/src/components/AssetGroup.vue
  2. +68
    -49
      app/src/components/Inventory.vue
  3. +132
    -129
      app/src/components/Search.vue
  4. +4
    -0
      src/main/java/com/moze/rms/config/JdbiFactory.java
  5. +47
    -5
      src/main/java/com/moze/rms/controller/InventoryController.java
  6. +81
    -0
      src/main/java/com/moze/rms/controller/SearchController.java
  7. +91
    -2
      src/main/java/com/moze/rms/dao/InventoryDAO.java
  8. +5
    -0
      src/main/java/com/moze/rms/dao/MappingColDAO.java
  9. +120
    -0
      src/main/java/com/moze/rms/dao/SearchDAO.java
  10. +189
    -65
      src/main/java/com/moze/rms/utils/ExcelExpoter.java

+ 23
- 12
app/src/components/AssetGroup.vue Просмотреть файл

@@ -1,6 +1,24 @@
<template>
<div>
<div>
<v-dialog
v-model="progress"
persistent
width="300"
>
<v-card
color="primary"
dark
>
<v-card-text>
查詢中...
<v-progress-linear
indeterminate
color="white"
class="mb-0"
></v-progress-linear>
</v-card-text>
</v-card>
</v-dialog>
<v-tabs
v-model='currentTab'
centered
@@ -469,7 +487,6 @@
</v-card>
</v-dialog>
</v-tabs>
</div>
</div>
</template>
<script>
@@ -486,6 +503,7 @@
dialogInsert: false,
dialogModify: false,
dialogNewAssertGroup: false,
progress: false,
// dialogSearch: false,
title: '資訊資產群組',
headers: [
@@ -555,6 +573,7 @@
},
async mounted() {
// this.getSelectItem();
this.progress = true;
this.getTabs();
this.getTypes();
this.inventoryItems = [];
@@ -569,6 +588,7 @@
computed: {},
watch: {
currentTab() {
this.progress = true;
this.getTypes();
this.getCols();
},
@@ -665,6 +685,7 @@
const tablename = this.assertGroup[this.currentTab] ? this.assertGroup[this.currentTab].value : 'hardware';
this.$axios.get(`/assert/allCols?tablename=${tablename}`).then((resp) => {
this.allCols = resp.data.data;
this.progress = false;
});
},
insertCol() {
@@ -741,16 +762,6 @@
});
}
},
exportFile() {
let yes = confirm('確定匯出');
if (yes) {
// this.$axios.delete(`/deleteOne?tablename=${this.tablename}&&id=${item.id}`).then(() => {
// this.getInventories();
// });

}

},
async insertAssertGroup() {
await this.$axios.post(`/assert/assertGroups`, {
assertGroupDescript: this.insertAssertGroupDescript,


+ 68
- 49
app/src/components/Inventory.vue Просмотреть файл

@@ -1,5 +1,24 @@
<template>
<div>
<v-dialog
v-model="progress"
persistent
width="300"
>
<v-card
color="primary"
dark
>
<v-card-text>
載入中...
<v-progress-linear
indeterminate
color="white"
class="mb-0"
></v-progress-linear>
</v-card-text>
</v-card>
</v-dialog>
<v-data-table class="" :headers="headers" :items="items"
disable-sort
fixed-header
@@ -48,6 +67,9 @@
</v-card-title>
<v-card-text>
<v-container>
<div class="red--text text--lighten-3 d-flex">1.請確認<p class="font-weight-bold red--text text--lighten-1 mb-0">匯入之類別</p>相符</div>
<div class="red--text text--lighten-3 d-flex">1.請確認<p class="font-weight-bold red--text text--lighten-1 mb-0">欄位名稱</p>一致</div>
<div class="red--text text--lighten-3 d-flex">3.<p class="font-weight-bold red--text text--lighten-1">欄位順序</p>不影響匯入</div>
<input id="file" type="file" @change="onFileChange" />
</v-container>
</v-card-text>
@@ -332,9 +354,6 @@
</div>
</template>
<script>
let cancel;
let CancelToken;
let cancel2;
export default {
name: '',
data() {
@@ -358,10 +377,11 @@
haveSearch:false,
dialogImport: false,
file: null,
progress: false,
}
},
async mounted() {
CancelToken = this.$axios.CancelToken;
this.progress = true;
this.getHeaders();
this.getInventories();
this.getTitle();
@@ -377,17 +397,14 @@
},
},
watch: {
tablename() {
async tablename() {
if (this.$route.params.tablename) {
this.headers = [];
this.items = [];
this.progress = true;
this.title = '';
this.selectItem = {};
this.insertItem = {};
this.getHeaders();
this.getInventories();
this.getTitle();
this.getSelectItem();
await this.getHeaders();
await this.getInventories();
await this.getTitle();
await this.getSelectItem();
}
},
},
@@ -402,21 +419,17 @@
oninput(item, key, val) {
this.$set(item, key, val);
},
getTitle() {
this.$axios.get(`/title?tablename=${this.tablename}`).then((resp) => {
async getTitle() {
await this.$axios.get(`/title?tablename=${this.tablename}`).then((resp) => {
this.title = `${resp.data.data}類`;
});
},
getHeaders() {
this.headers.push({'text': '', 'value': 'actions', sortable: false});
if (cancel) {
cancel();
}
this.$axios.get(`/headers?tablename=${this.tablename}`,{
cancelToken: new CancelToken(((c) => {
cancel = c;
})),
}).then((resp) => {
async getHeaders() {
await this.$axios.get(`/headers?tablename=${this.tablename}`)
.then((resp) => {
this.headers = [];
this.headers.push({'text': '', 'value': 'actions', sortable: false});
this.insertItem = {};
this.cols = resp.data.data;
resp.data.data.forEach((item) => {
let header = {'text': null, 'value': null};
@@ -435,16 +448,20 @@
});
});
},
getInventories() {
if (cancel2) {
cancel2();
}
this.$axios.get(`/inventory?tablename=${this.tablename}`,{
cancelToken: new CancelToken(((c) => {
cancel = c;
})),
}).then((resp) => {
async getInventories() {

await this.$axios.get(`/inventory?tablename=${this.tablename}`)
.then((resp) => {
this.items = [];
this.items = resp.data.data;
this.progress = false;
});
},
async getSelectItem() {

await this.$axios.get(`/selectItem?tablename=${this.tablename}`).then((resp) => {
this.selectItem = {};
this.selectItem = resp.data.data;
});
},
insertOne() {
@@ -475,11 +492,6 @@
isRequire(key) {
return this.isrequired.indexOf(key) >= 0;
},
getSelectItem() {
this.$axios.get(`/selectItem?tablename=${this.tablename}`).then((resp) => {
this.selectItem = resp.data.data;
});
},
modifyOne(item) {
item.tablename = this.tablename;
this.$axios.put(`/inventory?`, item).then(() => {
@@ -523,11 +535,6 @@
self.searchItem[key] = null;
});
this.getInventories();
// this.searchItem = {};
// await this.cols.forEach((item) => {
// this.searchItem[item.colname] = null;
//
// });
this.haveSearch = false;
},
onFileChange(e) {
@@ -540,6 +547,7 @@
},
importFile() {
const formData = new FormData();
formData.append('tablename', this.tablename);
formData.append('file', this.file);
this.$axios.post(`/importFile`, formData).then(() => {
document.getElementById('file').value = null;
@@ -552,12 +560,23 @@
exportFile() {
let yes = confirm('確定匯出');
if (yes) {
// this.$axios.delete(`/deleteOne?tablename=${this.tablename}&&id=${item.id}`).then(() => {
// this.getInventories();
// });

this.$axios.post(`/exportFile`, {items: this.items, info: {tablename: this.tablename}}, {responseType: 'blob'})
.then((resp) => {
console.log(resp.headers['filename']);
const blob = new Blob([resp.data], {type: "application/vnd.ms-excel;charset=utf-8"});
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = (e) => {
const a = document.createElement('a');
a.download = resp.headers['filename'];
a.href = e.target.result;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
}
);
}

}

}


+ 132
- 129
app/src/components/Search.vue Просмотреть файл

@@ -1,13 +1,30 @@
<template>
<v-container fluid>
<v-row justify="center" dense class="mt-1">
<v-dialog
v-model="progress"
persistent
width="300"
>
<v-card
color="primary"
dark
>
<v-card-text>
查詢中...
<v-progress-linear
indeterminate
color="white"
class="mb-0"
></v-progress-linear>
</v-card-text>
</v-card>
</v-dialog>
<v-row justify="center" dense class="ma-0 pa-0">
<v-col cols="4">
<v-text-field outlined prepend-inner-icon="mdi-magnify" rounded />
<v-text-field v-model="text" dense outlined prepend-inner-icon="mdi-magnify" hide-details rounded v-on:keyup.enter="search"/>
</v-col>
</v-row>
<v-data-table class="pa-3 pt-5" :headers="headers" :items="items">
<template v-slot:top>
<v-toolbar flat>
<v-toolbar flat v-if="result !== null">
<v-toolbar-title class="title font-weight-bold">搜尋結果</v-toolbar-title>
<v-divider
class="mx-4"
@@ -24,8 +41,47 @@
<v-icon >mdi-file-export-outline</v-icon>
</v-btn>
</v-toolbar>
</template>
</v-data-table>
<v-tabs
v-if="result !== null"
v-model='currentTab'
centered
fixed-tabs
background-color='grey lighten-4'
show-arrows
>
<!-- <v-tab-->
<!-- v-for='(item, index) in assertGroup'-->
<!-- :key='index'-->
<!-- class=' font-weight-bold'-->
<!-- >-->
<!-- <v-icon small>{{ item.text }}</v-icon>-->
<!-- </v-tab>-->
<div
v-for='(item, index) in assertGroup'
:key='index'
class="d-flex">
<v-tab
v-if="result[item.value]"
class=' font-weight-bold'
>
<v-icon small>{{ item.text }}</v-icon>
</v-tab>
</div>
<v-tabs-items v-model='currentTab'>

<div
v-for='(item, index) in assertGroup'
:key='index'
class="flex-fill">
<v-tab-item
v-if="result[item.value]"
>
<v-data-table v-if="result[item.value]" :headers="allHeaders[item.value]" :items="result[item.value]" >
</v-data-table>
</v-tab-item>
</div>
</v-tabs-items>
</v-tabs>

</v-container>
</template>
@@ -34,145 +90,92 @@
name: '',
data() {
return {
dialogInsert: false,
dialogModify: false,
dialogSearch: false,
title: '',
headers: [],
cols: {},
items: [],
select: [],
required: [],
insertItem: {},
modifyItem: {},
selectItem: {},
searchItem: {},
text: '',
result: null,
headers: {},
currentTab: 0,
assertGroup: [],
allHeaders: {},
progress: false
}
},
async mounted() {
this.getHeaders();
this.getInventories();
this.getTitle();
this.getSelectItem();
},
computed: {
tablename() {
return 'hardware';
},
mounted() {
this.getTabs();

},
watch: {
async tablename() {
if (this.$route.params.tablename) {
this.headers = [];
this.items = [];
this.title = '';
this.selectItem = {};
this.insertItem = {};
this.getHeaders();
this.getInventories();
this.getTitle();
this.getSelectItem();
}
},
currentTab() {
// this.tablename = this.assertGroup[this.currentTab].value;
// console.log(this.tablename);
// this.getHeaders();
},
result() {
Object.keys(this.result).forEach((key) => {
this.getHeaders(key);
})
},
allHeaders() {
this.$forceUpdate();
}
},
methods: {
log() {
alert('as');
},
oninput(item, key, val) {
this.$set(item, key, val);
},
getTitle() {
this.$axios.get(`/title?tablename=${this.tablename}`).then((resp) => {
this.title = `${resp.data.data}類`;
});
},
getHeaders() {
this.$axios.get(`/headers?tablename=${this.tablename}`).then((resp) => {
this.cols = resp.data.data;
async getTabs() {
await this.$axios.get(`/assert/assertGroups`).then((resp) => {
this.assertGroup = [];
resp.data.data.forEach((item) => {
let header = {'text': null, 'value': null};
header.text = item.descript;
header.value = item.colname;
this.headers.push(header);
if (item.select === 'true') {
this.select.push(item.colname);
}
if (item.require === 'true') {
this.required.push(item.colname);
}
this.insertItem[item.colname] = null;
this.searchItem[item.colname] = null;
header.text = item.descript;
header.value = item.tablename;
this.assertGroup.push(header);
});
this.headers.push({'text': '', 'value': 'actions', sortable: false});
});
},
getInventories() {
this.$axios.get(`/inventory?tablename=${this.tablename}`).then((resp) => {
this.items = resp.data.data;
});
},
insertOne() {
this.insertItem.tablename = this.tablename;
this.$axios.post(`/inventory?`, this.insertItem).then(() => {
delete this.insertItem.tablename;
this.getInventories();
this.close();
}
);
},
close() {
this.dialogInsert = false;
this.dialogModify = false;
this.dialogSearch = false;
},
isDisabled(key) {
const disabledKey = ['id'];
return disabledKey.indexOf(key) >= 0;
},
isTextField(key) {
return this.select.indexOf(key) < 0;
},
isSelect(key) {
return this.select.indexOf(key) >= 0;
},
isRequire(key) {
return this.required.indexOf(key) >= 0;
},
getSelectItem() {
this.$axios.get(`/selectItem?tablename=${this.tablename}`).then((resp) => {
this.selectItem = resp.data.data;
});
},
modifyOne(item) {
item.tablename = this.tablename;
this.$axios.put(`/inventory?`, item).then(() => {
this.getInventories();
this.close();
}
);
},
deleteOne(item) {
let yes = confirm('確定刪除');
if (yes) {
this.$axios.delete(`/deleteOne?tablename=${this.tablename}&&id=${item.id}`).then(() => {
this.getInventories();
alert('已刪除');

async getHeaders(key) {
await this.$axios.get(`/headers?tablename=${key}`)
.then(async (resp) => {
const headers = [];
await resp.data.data.forEach((item) => {
let header = {'text': null, 'value': null};
header.text = item.descript;
header.value = item.colname;
headers.push(header);
});
this.allHeaders[key] = headers;
});
}
console.log(item);
},
search() {
this.progress = true;
this.$axios.get(`/search/search?text=${this.text}`).then((resp) => {
Object.keys(resp.data.data).forEach(async (key) => {
await this.getHeaders(key);
});
setTimeout(() => {this.result = resp.data.data; this.progress = false;}, 500);
// this.result = resp.data.data;
});
},
exportFile() {
let yes = confirm('確定匯出');
if (yes) {
// this.$axios.delete(`/deleteOne?tablename=${this.tablename}&&id=${item.id}`).then(() => {
// this.getInventories();
// });

this.$axios.post(`/search/exportFileAllGroup`, this.result, {responseType: 'blob'})
.then((resp) => {
console.log(resp.headers['filename']);
const blob = new Blob([resp.data], {type: "application/vnd.ms-excel;charset=utf-8"});
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = (e) => {
const a = document.createElement('a');
a.download = resp.headers['filename'];
a.href = e.target.result;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
}
);
}

}

}
},
},
}
</script>

+ 4
- 0
src/main/java/com/moze/rms/config/JdbiFactory.java Просмотреть файл

@@ -75,5 +75,9 @@ public class JdbiFactory {
return jdbi.onDemand(AssertDAO.class);
}

@Bean
public SearchDAO searchDAO(Jdbi jdbi) {
return jdbi.onDemand(SearchDAO.class);
}

}

+ 47
- 5
src/main/java/com/moze/rms/controller/InventoryController.java Просмотреть файл

@@ -4,13 +4,18 @@ package com.moze.rms.controller;
import com.moze.rms.dao.InventoryDAO;
import com.moze.rms.dao.MappingColDAO;
import com.moze.rms.dao.MappingTableDAO;
import com.moze.rms.dao.SearchDAO;
import com.moze.rms.entity.dto.SelectItemDTO;
import com.moze.rms.entity.model.MappingCol;
import com.moze.rms.utils.ExcelExpoter;
import com.moze.rms.utils.ExcelImporter;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
import java.util.function.Function;
@@ -29,6 +34,9 @@ public class InventoryController {
@Autowired
InventoryDAO inventoryDAO;

@Autowired
SearchDAO searchDAO;


@GetMapping("/routes")
public JsonResult getRoutes() {
@@ -56,6 +64,8 @@ public class InventoryController {
public JsonResult insertInventory(@RequestBody Map<String, Object> data) {
System.out.println(data);
inventoryDAO.insertOne(data);
Integer id = inventoryDAO.findId(data);
searchDAO.insertSearch(id, data);
return new JsonResult(StatusCode.SUCCESS, null);
}

@@ -63,6 +73,7 @@ public class InventoryController {
public JsonResult modifyInventory(@RequestBody Map<String, Object> data) {
try {
inventoryDAO.modifyInventory(data);
searchDAO.modifySearch(data);
return new JsonResult(StatusCode.SUCCESS, null);
} catch (Exception e) {
return new JsonResult(StatusCode.SYS_ERROR, e.getMessage());
@@ -81,6 +92,7 @@ public class InventoryController {
System.out.println(tablename);
System.out.println(id);
inventoryDAO.deleteByTablenameAndId(tablename, id);
searchDAO.deleteFromSearch(tablename, id);
return new JsonResult(StatusCode.SUCCESS, null);
}

@@ -93,22 +105,52 @@ public class InventoryController {
}

@PostMapping("/importFile")
public JsonResult importFile(@RequestParam(required = false) MultipartFile file) throws IOException, InvalidFormatException {
public JsonResult importFile(String tablename, @RequestParam(required = false) MultipartFile file) throws IOException, InvalidFormatException {

File f = File.createTempFile(file.getOriginalFilename().split("\\.")[0], file.getOriginalFilename().split("\\.")[1]);
System.out.println(f.getName());
file.transferTo(f);

ExcelImporter excelImporter = new ExcelImporter(f);
List<Map<String, String>> data = excelImporter.readAll().get("工作表1");

ExcelImporter excelImporter2 = new ExcelImporter(f);
System.out.println(excelImporter2.readAll());
List<MappingCol> mappingCols = mappingColDAO.findByTable(tablename);

inventoryDAO.importInventories(tablename, mappingCols, data, searchDAO);
f.deleteOnExit();

return new JsonResult(StatusCode.SUCCESS, null);
}

@PostMapping("/exportFile")
public void exportFile(@RequestBody Map<String, Object> data, HttpServletResponse resp) throws IOException, InvalidFormatException {

List<Map<String, Object>> items = (List<Map<String, Object>>) data.get("items");
Map<String, String> info = (Map<String, String>) data.get("info");

return new JsonResult(StatusCode.SUCCESS, null);
List<MappingCol> mappingCols = mappingColDAO.findByTable(info.get("tablename"));

ArrayList<String> titleKeyList= new ArrayList<>();
Map<String, String> titleMap = new ManagedMap<>();
for(MappingCol m: mappingCols) {
titleKeyList.add(m.getColname());
titleMap.put(m.getColname(), m.getDescript());
}
ExcelExpoter excelExpoter = new ExcelExpoter("");
excelExpoter.expoerDataExcel(resp, titleKeyList, titleMap, items, info.get("tablename"));
}

@GetMapping("/allHeaders")
public JsonResult getAllHeaders() {


List<MappingCol> mappingCols = mappingColDAO.findAll();

mappingCols.stream().collect(Collectors.groupingBy(MappingCol::getTablename));
System.out.println(mappingCols.stream().collect(Collectors.groupingBy(MappingCol::getTablename)));

return new JsonResult(StatusCode.SUCCESS, mappingCols.stream().collect(Collectors.groupingBy(MappingCol::getTablename)));

}


}

+ 81
- 0
src/main/java/com/moze/rms/controller/SearchController.java Просмотреть файл

@@ -0,0 +1,81 @@
package com.moze.rms.controller;


import com.moze.rms.dao.MappingColDAO;
import com.moze.rms.dao.MappingTableDAO;
import com.moze.rms.dao.SearchDAO;
import com.moze.rms.entity.model.MappingCol;
import com.moze.rms.entity.model.MappingTable;
import com.moze.rms.utils.ExcelExpoter;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@RequestMapping("/api/search")
@RestController
public class SearchController {


@Autowired
SearchDAO searchDAO;

@Autowired
MappingTableDAO mappingTableDAO;

@Autowired
MappingColDAO mappingColDAO;

@GetMapping("/search")
public JsonResult search(@RequestParam String text) {

System.out.println(text);

List<MappingTable> tables = mappingTableDAO.findAll();

Map<String, List<Map<String, Object>>> result = new HashMap<>();

for(MappingTable m : tables) {
if (searchDAO.searchFromTable(m.getTablename(), text).size() > 0) {
result.put(m.getTablename(), searchDAO.searchFromTable(m.getTablename(), text));
}

}

return new JsonResult(StatusCode.SUCCESS, result);
}


@PostMapping("/exportFileAllGroup")
public void exportFileAllGroup(@RequestBody Map<String, List<Map<String, Object>>> data, HttpServletResponse resp) throws IOException, InvalidFormatException {



Iterator<Map.Entry<String, List<Map<String, Object>>>> iterator = data.entrySet().iterator();


Map<String, ArrayList<String>>titleKeyLists = new ManagedMap<>();
Map<String, Map<String, String>> titleMaps = new ManagedMap<>();
while (iterator.hasNext()) {
Map.Entry<String, List<Map<String, Object>>> next = iterator.next();
String key = next.getKey();
List<MappingCol> mappingCols = mappingColDAO.findByTable(key);
ArrayList<String> titleKeyList= new ArrayList<>();
Map<String, String> titleMap = new ManagedMap<>();
for(MappingCol m: mappingCols) {
titleKeyList.add(m.getColname());
titleMap.put(m.getColname(), m.getDescript());
}
titleKeyLists.put(key, titleKeyList);
titleMaps.put(key, titleMap);

}
ExcelExpoter excelExpoter = new ExcelExpoter("");
excelExpoter.expoerDataExcelMultiSheet(resp, titleKeyLists, titleMaps, data, "");
}

}

+ 91
- 2
src/main/java/com/moze/rms/dao/InventoryDAO.java Просмотреть файл

@@ -2,19 +2,21 @@ package com.moze.rms.dao;


import com.moze.rms.entity.dto.SelectItemDTO;
import com.moze.rms.entity.model.MappingCol;
import org.jdbi.v3.core.Handle;
import org.jdbi.v3.sqlobject.SqlObject;
import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public interface InventoryDAO extends SqlObject {


@RegisterBeanMapper(Object.class)
default List<Map<String, Object>> getInventoryByTablename(String tablename) {
Handle handle = this.getHandle();
@@ -72,6 +74,55 @@ public interface InventoryDAO extends SqlObject {
handle.execute(sql);
}

default Integer findId(Map<String, Object> data) {

Handle handle = this.getHandle();

String sql = "select id from " + data.get("tablename") + " where ";
Iterator<Map.Entry<String, Object>> iterator = data.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> next = iterator.next();
String key = next.getKey();
Object value = next.getValue().toString();
if (key != "tablename" && key != "id") {
if (value != null) {
sql += key + " = '" + value + "' and ";
} else {
sql += key + " = " + value + " and ";
}
}
}
sql = sql.substring(0, sql.length() - 4);

return handle.createQuery(sql).mapTo(Integer.class).one();
}


default Integer findId2(Map<String, String> data) {

Handle handle = this.getHandle();

String sql = "select top 1 id from " + data.get("tablename") + " where ";
Iterator<Map.Entry<String, String>> iterator = data.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> next = iterator.next();
String key = next.getKey();
Object value = next.getValue();
if (key != "tablename" && key != "id") {
if (value != null) {
sql += key + " = '" + value + "' and ";
} else {
sql += key + " = '' and ";
}
}
}
sql = sql.substring(0, sql.length() - 4);


return handle.createQuery(sql).mapTo(Integer.class).one();
}



@RegisterBeanMapper(Object.class)
default List<Map<String, Object>> search(Map<String, Object> data) {
@@ -83,7 +134,6 @@ public interface InventoryDAO extends SqlObject {
Map.Entry<String, Object> next = iterator.next();
String key = next.getKey();
Object value = next.getValue();
System.out.println(key);
if (key != "tablename" && key != "id" && value != null) {
sql += " " + key + " like '%" + value + "%' and";
}
@@ -92,4 +142,43 @@ public interface InventoryDAO extends SqlObject {
System.out.println(sql);
return handle.createQuery(sql).mapToMap().list();
}

default void importInventories(String tablename, List<MappingCol> mappingCols, List<Map<String, String>> datas, SearchDAO searchDAO) {

Handle handle = this.getHandle();



for (Map<String, String> data : datas) {
String cols = "";
String values = "";
Map<String, String> tmpData = new HashMap<>();
for(MappingCol m : mappingCols) {
if (!m.getColname().equals("id")) {
if (data.get(m.getDescript()) != null) {
cols += " " + m.getColname() + ",";
values += " '" + data.get(m.getDescript()).replace("'", "`") + "',";
tmpData.put(m.getColname(), data.get(m.getDescript()).replace("'", "`"));
} else {
cols += " " + m.getColname() + ",";
values += " '',";
tmpData.put(m.getColname(), data.get(m.getDescript()));
}
}
}
cols = cols.substring(0, cols.length() - 1);
values = values.substring(0, values.length() - 1);

String sql = "insert into " + tablename + "(" + cols + ") values (" + values + ")";
System.out.println(sql);
handle.createUpdate(sql).execute();

tmpData.put("tablename", tablename);
Integer id = findId2(tmpData);
searchDAO.insertSearch2(id, tmpData);

}
}


}

+ 5
- 0
src/main/java/com/moze/rms/dao/MappingColDAO.java Просмотреть файл

@@ -6,6 +6,7 @@ import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
import org.jdbi.v3.sqlobject.statement.SqlQuery;

import java.util.List;
import java.util.Map;

@RegisterBeanMapper(MappingCol.class)
public interface MappingColDAO {
@@ -13,4 +14,8 @@ public interface MappingColDAO {

@SqlQuery("select * from mapping.mapping_col where tablename = ? order by convert(int, [index]);")
List<MappingCol> findByTable(String tablename);


@SqlQuery("select * from mapping.mapping_col order by convert(int, [index]);")
List<MappingCol> findAll();
}

+ 120
- 0
src/main/java/com/moze/rms/dao/SearchDAO.java Просмотреть файл

@@ -0,0 +1,120 @@
package com.moze.rms.dao;

import org.jdbi.v3.core.Handle;
import org.jdbi.v3.sqlobject.SqlObject;
import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
import org.jdbi.v3.sqlobject.statement.SqlUpdate;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

public interface SearchDAO extends SqlObject {


// @RegisterBeanMapper(Object.class)
// default List<Map<String, Object>> search(Map<String, Object> data) {
// Handle handle = this.getHandle();
// String sql = "select * from " + data.get("tablename") + " where";
// data.remove("tablename");
// Iterator<Map.Entry<String, Object>> iterator = data.entrySet().iterator();
// while (iterator.hasNext()) {
// Map.Entry<String, Object> next = iterator.next();
// String key = next.getKey();
// Object value = next.getValue();
// if (key != "tablename" && key != "id" && value != null) {
// sql += " " + key + " like '%" + value + "%' and";
// }
// }
// sql = sql.substring(0, sql.length() - 3);
// System.out.println(sql);
// return handle.createQuery(sql).mapToMap().list();
// }


@RegisterBeanMapper(Object.class)
default List<Map<String, Object>> searchFromTable(String tablename, String text) {

Handle handle = this.getHandle();
String sql = "select ";
sql += tablename + ".*";
sql += "from search ";
sql += "join " + tablename + " on search.id = " + tablename + ".id ";
sql += " and search.tablename = '" + tablename + "' ";
sql += "where text like '%' + '" + text + "' + '%' order by id";


return handle.createQuery(sql).mapToMap().list();
}

default void insertSearch(Integer id, Map<String, Object> data) {
Handle handle = this.getHandle();

String text = "";
Iterator<Map.Entry<String, Object>> iterator = data.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> next = iterator.next();
String key = next.getKey();
Object value = next.getValue().toString();
if (key != "id" && key != "tablename" && value != null) {
text += value + " ";
}
}
String sql = "insert into search values (";
sql += "'" + data.get("tablename") + "',";
sql += "'" + id + "',";
sql += "'" + text + "'";
sql += ")";
handle.createUpdate(sql).execute();
}

default void insertSearch2(Integer id, Map<String, String> data) {
Handle handle = this.getHandle();

String text = "";
Iterator<Map.Entry<String, String>> iterator = data.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> next = iterator.next();
String key = next.getKey();
Object value = next.getValue();
if (key != "id" && key != "tablename" && value != null) {
text += value.toString() + " ";
}
}
String sql = "insert into search values (";
sql += "'" + data.get("tablename") + "',";
sql += "'" + id + "',";
sql += "'" + text + "'";
sql += ")";
handle.createUpdate(sql).execute();
}


default void modifySearch( Map<String, Object> data) {

Handle handle = this.getHandle();

String text = "";
Iterator<Map.Entry<String, Object>> iterator = data.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> next = iterator.next();
String key = next.getKey();
Object value = next.getValue();
if (key != "id" && key != "tablename" && value != null) {
text += value.toString() + " ";
}
}
String sql = "update search set text = ";
sql += "'" + text + "'";
sql += "where tablename = ''" + data.get("tablename") + "' and id = '" + data.get("id").toString() + "'";

handle.createUpdate(sql).execute();
}

@SqlUpdate("delete from search where tablename = ? and id = ?")
void deleteFromSearch(String tablename, String id);

// default void bulkinsertSearch(String tablename, String id , List<Map<String, Object>> datas) {
// Handle handle = this.getHandle();
// }
}

+ 189
- 65
src/main/java/com/moze/rms/utils/ExcelExpoter.java Просмотреть файл

@@ -1,40 +1,31 @@
package com.moze.rms.utils;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import java.io.*;
import java.util.*;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;


public class ExcelExpoter {
private String outputPath;
private String nullString;
private Set<String> columnAutoSized = new HashSet<>();
List<SheetInfo> sheets = new LinkedList<>();
private String outputPath;
private String nullString;
private Set<String> columnAutoSized = new HashSet<>();
List<SheetInfo> sheets = new LinkedList<>();

public ExcelExpoter(String outputPath) {
this.outputPath = outputPath;
this.nullString = "<NULL>";
}
public ExcelExpoter(String outputPath) {
this.outputPath = outputPath;
this.nullString = "<NULL>";
}

public ExcelExpoter(String outputPath, String nullString) {
this.outputPath = outputPath;
this.nullString = nullString;
}
public ExcelExpoter(String outputPath, String nullString) {
this.outputPath = outputPath;
this.nullString = nullString;
}

// public void export() throws FileNotFoundException, IOException {
// try (FileOutputStream outputStream = new FileOutputStream(outputPath);
@@ -48,9 +39,9 @@ public class ExcelExpoter {
// }
// }

public void addSheet(String sheetName, Map<String, String> headerMap, List<?> data) {
sheets.add(new SheetInfo(sheetName, headerMap, data));
}
public void addSheet(String sheetName, Map<String, String> headerMap, List<?> data) {
sheets.add(new SheetInfo(sheetName, headerMap, data));
}

// public void export(String sheetName, Map<String, String> headerMap, List<?> data) throws FileNotFoundException, IOException {
// try (FileOutputStream outputStream = new FileOutputStream(outputPath);
@@ -62,8 +53,8 @@ public class ExcelExpoter {
// }
// }

private void exportSheet(XSSFWorkbook workbook, String sheetName, Map<String, String> headerMap, List<?> data) {
XSSFSheet sheet = workbook.createSheet(sheetName);
private void exportSheet(XSSFWorkbook workbook, String sheetName, Map<String, String> headerMap, List<?> data) {
XSSFSheet sheet = workbook.createSheet(sheetName);

int rowCount = 0;

@@ -71,7 +62,7 @@ public class ExcelExpoter {
if (headerMap == null) {
headerMap = new LinkedHashMap<>();
if (!data.isEmpty()) {
for(String k: JsonUtil.pojo2Map(data.get(0)).keySet()) {
for (String k : JsonUtil.pojo2Map(data.get(0)).keySet()) {
headerMap.put(k, k);
}
}
@@ -88,7 +79,7 @@ public class ExcelExpoter {
Row row = sheet.createRow(rowCount++);
int columnCount = 0;

for(String v: headerMap.values()) {
for (String v : headerMap.values()) {
Cell cell = row.createCell(columnCount++);
cell.setCellValue(v);
cell.setCellStyle(headerCellStyle);
@@ -101,11 +92,11 @@ public class ExcelExpoter {

for (Object item : data) {
@SuppressWarnings("unchecked")
Map<String, Object> obj = item instanceof Map ? (Map<String, Object>)item: JsonUtil.pojo2Map(item);
Map<String, Object> obj = item instanceof Map ? (Map<String, Object>) item : JsonUtil.pojo2Map(item);
row = sheet.createRow(rowCount++);

columnCount = 0;
for(String k: headerMap.keySet()) {
for (String k : headerMap.keySet()) {
Object v = obj.get(k);
Cell cell = row.createCell(columnCount++);
String value = v == null ? nullString : v.toString();
@@ -120,57 +111,190 @@ public class ExcelExpoter {
}
System.out.println("[" + sheetName + "] Created all row " + rowCount);
autoSizeColumn(sheet);
}

private void autoSizeColumn(XSSFSheet sheet) {
if (columnAutoSized.contains(sheet.getSheetName()))
return;
System.out.println("Start auto size columns");
int maxWidth = 256 * 120;
int minWidth = 256 * 16;
int rowCount = sheet.getRow(0).getLastCellNum();
System.out.println(rowCount);
for (int j = 0; j < rowCount; j++) {
sheet.autoSizeColumn(j);
if (sheet.getColumnWidth(j) > maxWidth) {
sheet.setColumnWidth(j, maxWidth);
}
if (sheet.getColumnWidth(j) < minWidth) {
sheet.setColumnWidth(j, minWidth);
}
}
columnAutoSized.add(sheet.getSheetName());
System.out.println("End auto size columns");
}

private static class SheetInfo {
private String sheetName;
private Map<String, String> headerMap;
private List<?> data;
}

private void autoSizeColumn(XSSFSheet sheet) {
if (columnAutoSized.contains(sheet.getSheetName()))
return;
System.out.println("Start auto size columns");
int maxWidth = 256 * 120;
int minWidth = 256 * 16;
int rowCount = sheet.getRow(0).getLastCellNum();
System.out.println(rowCount);
for (int j = 0; j < rowCount; j++) {
sheet.autoSizeColumn(j);
if (sheet.getColumnWidth(j) > maxWidth) {
sheet.setColumnWidth(j, maxWidth);
}
if (sheet.getColumnWidth(j) < minWidth) {
sheet.setColumnWidth(j, minWidth);
}
}
columnAutoSized.add(sheet.getSheetName());
System.out.println("End auto size columns");
}

private static class SheetInfo {
private String sheetName;
private Map<String, String> headerMap;
private List<?> data;

public SheetInfo(String sheetName, Map<String, String> headerMap, List<?> data) {
super();
this.sheetName = sheetName;
this.headerMap = headerMap;
this.data = data;
}

public String getSheetName() {
return sheetName;
}

public void setSheetName(String sheetName) {
this.sheetName = sheetName;
}

public Map<String, String> getHeaderMap() {
return headerMap;
}

public void setHeaderMap(Map<String, String> headerMap) {
this.headerMap = headerMap;
}

public List<?> getData() {
return data;
}

public void setData(List<?> data) {
this.data = data;
}

}
}


public void expoerDataExcel(HttpServletResponse response, ArrayList<String> titleKeyList, Map<String, String> titleMap, List<Map<String, Object>> src_list, String filename) throws IOException {

String xlsFile_name = filename + ".xls"; //輸出xls檔名稱
//記憶體中只建立100個物件
Workbook wb = new SXSSFWorkbook(100); //關鍵語句
Sheet sheet = null; //工作表物件
Row nRow = null; //行物件
Cell nCell = null; //列物件

int rowNo = 0; //總行號
int pageRowNo = 0; //頁行號

for (int k = 0; k < src_list.size(); k++) {
Map<String, Object> srcMap = src_list.get(k);
//寫入300000條後切換到下個工作表
if (rowNo % 300000 == 0) {
System.out.println("Current Sheet:" + rowNo / 300000);
sheet = wb.createSheet("工作簿" + (rowNo / 300000));//建立新的sheet物件
sheet = wb.getSheetAt(rowNo / 300000); //動態指定當前的工作表
pageRowNo = 0; //新建了工作表,重置工作表的行號為0
// -----------定義表頭-----------
nRow = sheet.createRow(pageRowNo++);
// 列數 titleKeyList.size()
for (int i = 0; i < titleKeyList.size(); i++) {
Cell cell_tem = nRow.createCell(i);
cell_tem.setCellValue(titleMap.get(titleKeyList.get(i)));
}
rowNo++;
// ---------------------------
}
rowNo++;
nRow = sheet.createRow(pageRowNo++); //新建行物件

// 行,獲取cell值
for (int j = 0; j < titleKeyList.size(); j++) {
nCell = nRow.createCell(j);
if (srcMap.get(titleKeyList.get(j)) != null) {
nCell.setCellValue(srcMap.get(titleKeyList.get(j)).toString());
} else {
nCell.setCellValue("");
}
}
}
System.out.println(wb.getSheet("工作簿0").getRow(1));
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("filename" , xlsFile_name);
response.setHeader("Content-disposition" , "attachment;filename=" + xlsFile_name);
response.flushBuffer();
OutputStream outputStream = response.getOutputStream();
wb.write(response.getOutputStream());
wb.close();
outputStream.flush();
outputStream.close();
}


public void expoerDataExcelMultiSheet(HttpServletResponse response, Map<String, ArrayList<String>> titleKeyLists, Map<String, Map<String, String>> titleMaps, Map<String, List<Map<String, Object>>> src_lists, String filename) throws IOException {

String xlsFile_name = "資產清冊.xls"; //輸出xls檔名稱
//記憶體中只建立100個物件
Workbook wb = new SXSSFWorkbook(100); //關鍵語句
Iterator<Map.Entry<String, List<Map<String, Object>>>> iterator = src_lists.entrySet().iterator();
while (iterator.hasNext()) {
Sheet sheet = null; //工作表物件
Row nRow = null; //行物件
Cell nCell = null; //列物件

int rowNo = 0; //總行號
int pageRowNo = 0; //頁行號


Map.Entry<String, List<Map<String, Object>>> next = iterator.next();
String key = next.getKey();
List<Map<String, Object>> src_list = next.getValue();

for (int k = 0; k < src_list.size(); k++) {
Map<String, Object> srcMap = src_list.get(k);
//寫入300000條後切換到下個工作表
if (rowNo % 300000 == 0) {
System.out.println("Current Sheet:" + key);
sheet = wb.createSheet(key);//建立新的sheet物件
// sheet = wb.getSheetAt(k); //動態指定當前的工作表
pageRowNo = 0; //新建了工作表,重置工作表的行號為0
// -----------定義表頭-----------
nRow = sheet.createRow(pageRowNo++);
// 列數 titleKeyList.size()
for (int i = 0; i < titleKeyLists.get(key).size(); i++) {
Cell cell_tem = nRow.createCell(i);
cell_tem.setCellValue(titleMaps.get(key).get(titleKeyLists.get(key).get(i)));
}
rowNo++;
// ---------------------------
}
rowNo++;
nRow = sheet.createRow(pageRowNo++); //新建行物件

// 行,獲取cell值
for (int j = 0; j < titleKeyLists.get(key).size(); j++) {
nCell = nRow.createCell(j);
if (srcMap.get(titleKeyLists.get(key).get(j)) != null) {
nCell.setCellValue(srcMap.get(titleKeyLists.get(key).get(j)).toString());
} else {
nCell.setCellValue("");
}
}
if (k == src_list.size() - 1) {
rowNo = 0;
pageRowNo = 0;
}
}


}

response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("filename" ,xlsFile_name);
response.setHeader("Content-disposition" ,"attachment;filename="+xlsFile_name);
response.flushBuffer();
OutputStream outputStream = response.getOutputStream();
wb.write(response.getOutputStream());
wb.close();
outputStream.flush();
outputStream.close();
}
}

Загрузка…
Отмена
Сохранить