• 导入

      1. @ApiOperation(value = "导入文件", notes = "导入文件")
      2. @RequestMapping(value = "/importFile", method = {RequestMethod.POST})
      3. public ResultBean<Boolean> importFile(HttpServletRequest request, HttpServletResponse response) {
      4. MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
      5. MultipartFile multipartFile = multipartHttpServletRequest.getFile("file");
      6. try {
      7. return ResultUtil.success(kxDictionaryService.importFile(multipartFile));
      8. } catch (IOException e) {
      9. return ResultUtil.error();
      10. }
      11. }
      1. @Override
      2. public boolean importFile(MultipartFile multipartFile) throws IOException {
      3. // 临时文件
      4. File tempFile = new File(customConfigProperty.getTempDirPath()+ File.separator + "康熙管理临时文件.xlsx");
      5. multipartFile.transferTo(tempFile);
      6. EasyExcel.read(tempFile, KxDictionaryExcel.class, new ExcelDataListener<KxDictionaryExcel>(kxDictionaryMapper)).headRowNumber(1).sheet(0).doRead();
      7. return true;
      8. }

      ```java public class ExcelDataListener extends AnalysisEventListener {

      private Logger logger = LoggerFactory.getLogger(getClass());

      // 每隔1000条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 private static final int BATCH_COUNT = 1000;

      List list = new ArrayList();

      private ExcelMapper excelMapper;

      /**

      • 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来 */ public ExcelDataListener(ExcelMapper excelMapper) { this.excelMapper = excelMapper; }

        /**

      • 这个每一条数据解析都会来调用 */ @Override public void invoke(T data, AnalysisContext context) { logger.info(“解析到一条数据:{}”, JSON.toJSONString(data)); list.add(data); // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if (list.size() >= BATCH_COUNT) {

        1. saveData();
        2. // 存储完成清理 list
        3. list.clear();

        } }

        /**

      • 所有数据解析完成了 都会来调用 */ @Override public void doAfterAllAnalysed(AnalysisContext context) { // 这里也要保存数据,确保最后遗留的数据也存储到数据库 saveData(); logger.info(“所有数据解析完成!”); }

        /**

      • 加上存储数据库 */ private void saveData() { logger.info(“{}条数据,开始存储数据库!”, list.size()); excelMapper.saveExcelData(list); logger.info(“存储数据库成功!”); }

    }

    1. - 导出excel
    2. ```java
    3. @ApiOperation(value = "导出Excel")
    4. @RequestMapping(value="/exportExcel", method = {RequestMethod.POST})
    5. public void exportExcel(@RequestBody String[] ary){
    6. try {
    7. kxDictionaryService.exportExcel(Arrays.asList(ary));
    8. } catch (Exception e) {
    9. logger.error("导出Excel数据异常",e);
    10. e.printStackTrace();
    11. }
    12. }
    1. @Override
    2. public void exportExcel(List<String> list) {
    3. List<KxDictionary> data = baseMapper.selectBatchIds(list);
    4. // 临时文件路径
    5. File tempFilePath = new File(customConfigProperty.getTempDirPath());
    6. if(!tempFilePath.exists()) {
    7. tempFilePath.mkdirs();//创建目录
    8. }
    9. // 临时文件
    10. String temporaryFileName = customConfigProperty.getTempDirPath() + File.separator + "康熙管理.xlsx";
    11. // 模板文件
    12. String templateFileName = FileUtils.getPath() + File.separator + "康熙管理模板.xlsx";
    13. ExcelWriter excelWriter = EasyExcel.write(temporaryFileName).withTemplate(templateFileName).build();
    14. WriteSheet writeSheet = EasyExcel.writerSheet().build();
    15. excelWriter.fill(data, writeSheet);
    16. // 关闭流
    17. excelWriter.finish();
    18. try {
    19. FileDownLoad.download(temporaryFileName);
    20. } catch (BaseException e) {
    21. e.printStackTrace();
    22. }
    23. }

    image.png

    • 导出word

      1. @ApiOperation(value = "导出word")
      2. @RequestMapping(value="/exportWord", method = {RequestMethod.POST})
      3. public void exportWord(@RequestBody AncientTones entity){
      4. try {
      5. searchIndexService.exportWord(entity);
      6. } catch (Exception e) {
      7. logger.error("导出word数据异常",e);
      8. e.printStackTrace();
      9. }
      10. }
      1. @Override
      2. public void exportWord(AncientTones entity) {
      3. if (!StringUtils.isEmpty(entity.getYears())){
      4. entity.setCoding(this.handle(entity.getYears()));
      5. }
      6. List<AncientTones> data = searchIndexMapper.queryExcelData(entity);
      7. List<Map<String, Object>> list = new ArrayList<>();
      8. String str = "";
      9. for (int i = 0; i < data.size(); i++) {
      10. str = (i+1) + "、" + data.get(i).getChinesePrefix();
      11. if (!StringUtil.isBlank(data.get(i).getAntiCut())){
      12. str += "," + data.get(i).getAntiCut();
      13. }
      14. if (!StringUtil.isBlank(data.get(i).getCitation())){
      15. str += "。" + data.get(i).getCitation();
      16. }
      17. Map<String, Object> map = new HashMap<>();
      18. map.put("contexts",str);
      19. list.add(map);
      20. }
      21. Map<String, Object> dataMap = new HashMap<>();
      22. dataMap.put("list",list);
      23. String name = "古音检索记录.doc";
      24. try {
      25. InputStream templateStream = new ClassPathResource("template/古代音读.doc").getInputStream();
      26. InputStream asposeLicenseXmlStream = new ClassPathResource("license.xml").getInputStream();
      27. String path = customConfigProperty.getBaseFilePath() + name;
      28. boolean success = WordTempateUtil.wordAsAspose(asposeLicenseXmlStream, templateStream, path, "", dataMap);
      29. FileDownLoad.download(path);
      30. } catch (IOException | BaseException e) {
      31. e.printStackTrace();
      32. throw new RuntimeException("获取文件内容失败!" + e.getMessage());
      33. }
      34. }

      ```java package com.sw.anc.utils;

    import com.aspose.words.Document; import com.aspose.words.License; import org.apache.commons.lang.StringUtils; import org.springframework.core.io.ClassPathResource;

    import java.io.File; import java.io.InputStream; import java.util.Map;

    /**

    • @author 王健
    • @version 1.0.0
    • @description word导出工具类
    • @since 2019/12/19 1.0.0 */ public class WordTempateUtil {

      /**

      • @param stream 许可证文件流
      • @return boolean 是否成功
      • @create 王健 2019/12/19
      • @description 检测许可 */ public static boolean getLicense(InputStream stream) { boolean result = false; License license = new License(); try {

        1. license.setLicense(stream);
        2. result = true;

        } catch (Exception e) {

        1. e.printStackTrace();

        } return result; }

        /**

      • @return java.io.InputStream 许可证文件流
      • @create 王健 2019/12/19
      • @description 获取许可证文件流 */ public static InputStream getAsposeLicenseXmlStream() { InputStream asposeLicenseXmlStream = null; try {

        1. asposeLicenseXmlStream = new ClassPathResource("lib/license.xml").getInputStream();

        } catch (Exception e) {

        1. e.printStackTrace();

        } return asposeLicenseXmlStream; }

        /**

      • @param licenseStream 许可证文件流
      • @param templateStream 模板文件流
      • @param destdoc 存储位置
      • @param ImagePath 图片路径
      • @param map 数据
      • @return boolean 是否转换成功
      • @create 王健 2019/12/19
      • @description 将数据填充至模板 */ public static boolean wordAsAspose(InputStream licenseStream, InputStream templateStream, String destdoc, String ImagePath, Map map) { if (!getLicense(licenseStream)) {

        1. return false;

        } try {

        1. Document doc = new Document(templateStream);
        2. new WordTemplateParser(doc, map, ImagePath).parse();
        3. File file = new File(destdoc);
        4. String parent = file.getParent();
        5. if (StringUtils.isNotEmpty(parent)) {
        6. File parentFile = new File(parent);
        7. if (!parentFile.exists()) {
        8. parentFile.mkdirs();
        9. }
        10. }
        11. if (!file.exists()) {
        12. file.createNewFile();
        13. }
        14. doc.save(destdoc);
        15. return true;

        } catch (Exception e) {

        1. e.printStackTrace();
        2. throw new RuntimeException("归档发生异常!");

        } }

    }

    1. ```java
    2. package com.sw.anc.utils;
    3. import com.aspose.words.*;
    4. import com.google.common.collect.Lists;
    5. import com.google.common.collect.Maps;
    6. import com.sw.common.util.UUIDUtil;
    7. import org.apache.commons.lang.StringUtils;
    8. import java.util.*;
    9. import java.util.List;
    10. /**
    11. *@author 王健
    12. *@since 2019/12/19 1.0.0
    13. *@version 1.0.0
    14. *@description word模板转换类
    15. */
    16. public class WordTemplateParser {
    17. private Document doc;
    18. private Map<String, Object> data = Maps.newHashMap();
    19. private String[] fieldNames;
    20. private String imageFolder;
    21. /**
    22. * @create 王健 2019/12/19
    23. * @param doc 文档
    24. * @param data 数据
    25. * @param imageFolder 图片文件夹
    26. * @description 构造函数
    27. */
    28. public WordTemplateParser(Document doc, Map<String, Object> data, String imageFolder) {
    29. super();
    30. this.doc = doc;
    31. this.data = data;
    32. this.imageFolder = imageFolder;
    33. try {
    34. this.fieldNames = this.doc.getMailMerge().getFieldNames();
    35. } catch (Exception e) {
    36. e.printStackTrace();
    37. }
    38. }
    39. /**
    40. * @create 王健 2019/12/19
    41. * @description 模板解析函数
    42. */
    43. public void parse() throws Exception {
    44. this.doc.getMailMerge().setFieldMergingCallback(new AsposeWordMergeHandle("Image", this.imageFolder));
    45. this.mergeExecute(Arrays.asList(this.fieldNames), this.data);
    46. this.buildTables();
    47. }
    48. /**
    49. * @create 王健 2019/12/19
    50. * @param fieldNameList 字段集合
    51. * @param data 数据
    52. * @description 合并域数据
    53. */
    54. private void mergeExecute(List<String> fieldNameList, Map<String, Object> data) throws Exception {
    55. List<String> executeFieldNameList = Lists.newArrayList();
    56. List<Object> valueList = Lists.newArrayList();
    57. for (int i = 0; i < fieldNameList.size(); i++) {
    58. String fieldName = fieldNameList.get(i);
    59. if(fieldName.startsWith("Table")) continue;
    60. if(fieldName.startsWith("Image")) {
    61. fieldName = fieldName.substring("Image".length() + 1).trim();
    62. valueList.add(this.getMapValueByKey(fieldName.split(":")[0], data, String.class));
    63. }
    64. else {
    65. valueList.add(this.getMapValueByKey(fieldName, data, String.class));
    66. }
    67. executeFieldNameList.add(fieldName);
    68. }
    69. this.doc.getMailMerge().execute(executeFieldNameList.toArray(new String[executeFieldNameList.size()]), valueList.toArray(new Object[valueList.size()]));
    70. }
    71. /**
    72. * @create 王健 2019/12/19
    73. * @description 合并表格数据
    74. */
    75. @SuppressWarnings("unchecked")
    76. private void buildTables() throws Exception {
    77. Map<String, List<String>> tableNameChildrenMap = this.fieldNameGroup(Arrays.asList(this.fieldNames));
    78. Set<String> keySet = tableNameChildrenMap.keySet();
    79. for (String tableName : keySet) {
    80. DataTable dataTable = new DataTable(tableName);
    81. DataSet dataSet = new DataSet();
    82. dataSet.getTables().add(dataTable);
    83. this.buildDataTable(dataSet, dataTable, tableNameChildrenMap.get(tableName), "", this.getMapValueByKey(tableName, this.data, List.class));
    84. this.doc.getMailMerge().executeWithRegions(dataSet);
    85. }
    86. }
    87. /**
    88. * @create 王健 2019/12/19
    89. * @param dataSet 数据集
    90. * @param dataTable 数据表格
    91. * @param fieldNameList 字段集合
    92. * @param parent 父级
    93. * @param data 数据
    94. * @description 递归创建表格数据
    95. */
    96. @SuppressWarnings("unchecked")
    97. private void buildDataTable(DataSet dataSet, DataTable dataTable, List<String> fieldNameList, String parent, List<Map<String, Object>> data) throws Exception {
    98. addTableColumn(dataTable, fieldNameList);
    99. addTableColumnData(dataTable, parent, data);
    100. if(data == null || data.isEmpty()) return;
    101. dataSet.getTables().add(dataTable);
    102. Map<String, List<String>> tableNameChildrenMap = fieldNameGroup(fieldNameList);
    103. Set<String> keySet = tableNameChildrenMap.keySet();
    104. // boolean hasTableMerge = false;
    105. for (String tableName : keySet) {
    106. DataTable dataTableChild = dataSet.getTables().get(tableName);
    107. if(dataSet.getTables().get(tableName) == null) {
    108. dataTableChild = new DataTable(tableName);
    109. dataSet.getTables().add(dataTableChild);
    110. }
    111. for (Map<String, Object> map : data) {
    112. buildDataTable(dataSet, dataTableChild, tableNameChildrenMap.get(tableName), (String)map.get("id"), this.getMapValueByKey(tableName, map, List.class));
    113. // 关联数据并渲染
    114. if(dataTableChild.getRows().getCount() == 0) continue;
    115. }
    116. }
    117. dataSet.getTables().forEach(dataTableChild -> {
    118. dataSet.getRelations().add(new DataRelation(dataTable.getTableName() + "-relation-" + UUIDUtil.getUUID(), dataTable, dataTableChild, new String[] {"id"}, new String[] {"parent"}));
    119. });
    120. }
    121. /**
    122. * @create 王健 2019/12/19
    123. * @param dataTable 数据表格
    124. * @param columnNameList 列集合
    125. * @description 添加表格的列
    126. */
    127. private void addTableColumn(DataTable dataTable, List<String> columnNameList) {
    128. dataTable.getColumns().add("id"); // 主键
    129. dataTable.getColumns().add("guid");
    130. dataTable.getColumns().add("parent"); // 父节点
    131. dataTable.getColumns().add("row_index"); // 行号
    132. int tableDeep = 0;
    133. for (String columnName : columnNameList) {
    134. if(columnName.startsWith("TableStart")) {
    135. tableDeep ++;
    136. }
    137. else if(columnName.startsWith("TableEnd")) {
    138. tableDeep --;
    139. }
    140. else {
    141. if(tableDeep == 0) {
    142. if(columnName.startsWith("Image")) {
    143. columnName = columnName.substring("Image".length() + 1).trim();
    144. }
    145. dataTable.getColumns().add(columnName);
    146. }
    147. }
    148. }
    149. }
    150. /**
    151. * @create 王健 2019/12/19
    152. * @param fieldNameList 字段集合
    153. * @return java.util.Map<java.lang.String,java.util.List<java.lang.String>> 转换结果
    154. * @description 转换字段数据
    155. */
    156. private Map<String, List<String>> fieldNameGroup(List<String> fieldNameList) {
    157. Map<String, List<String>> tableNameChildrenMap = Maps.newHashMap();
    158. String tableName = null;
    159. boolean hasTableStartSign = false;
    160. for (int i = 0; i < fieldNameList.size(); i++) {
    161. String fieldName = fieldNameList.get(i);
    162. if(hasTableStartSign) {
    163. if(fieldName.startsWith("TableEnd")
    164. && fieldName.substring("TableEnd".length() + 1).equals(tableName)) {
    165. hasTableStartSign = false; // 标志table结束
    166. }
    167. else {
    168. tableNameChildrenMap.get(tableName).add(fieldName);
    169. }
    170. }
    171. else {
    172. if(fieldName.startsWith("TableStart")) {
    173. tableName = fieldName.substring("TableStart".length() + 1);
    174. if(!tableNameChildrenMap.containsKey(tableName)) {
    175. tableNameChildrenMap.put(tableName, Lists.newArrayList());
    176. }
    177. hasTableStartSign = true;
    178. }
    179. }
    180. }
    181. return tableNameChildrenMap;
    182. }
    183. /**
    184. * @create 王健 2019/12/19
    185. * @param dataTable 数据表格
    186. * @param parent 父级
    187. * @param data 数据
    188. * @description 添加表格数据
    189. */
    190. private void addTableColumnData(DataTable dataTable, String parent, List<Map<String, Object>> data) throws Exception {
    191. if(data == null || data.isEmpty()) {
    192. // DocumentBuilder builder = new DocumentBuilder(this.doc);
    193. // builder.moveToMergeField(dataTable.getTableName());
    194. // builder.insertHtml("aaaa");
    195. DataRow dataRow = dataTable.newRow();
    196. if(!StringUtils.isBlank(parent)) {
    197. String id = UUIDUtil.getUUID();
    198. dataRow.set(0, id); // id
    199. dataRow.set(2, parent); // parent
    200. }
    201. dataTable.getRows().add(dataRow);
    202. return;
    203. }
    204. int rowIndex = 0; // 行号
    205. for (Map<String, Object> map : data) {
    206. rowIndex ++;
    207. map.put("id", UUIDUtil.getUUID());
    208. map.put("parent", parent);
    209. map.put("row_index", rowIndex); // 设置行号
    210. DataRow dataRow = dataTable.newRow();
    211. DataColumnCollection dataColumnCollection = dataTable.getColumns();
    212. Iterator<DataColumn> iterator = dataColumnCollection.iterator();
    213. int index = 0;
    214. while(iterator.hasNext()) {
    215. DataColumn dataColumn = iterator.next();
    216. String[] columnNameSplit = dataColumn.getColumnName().split(":");
    217. dataRow.set(index, map.get(columnNameSplit[0]));
    218. index ++;
    219. }
    220. dataTable.getRows().add(dataRow);
    221. }
    222. }
    223. /**
    224. * @create 王健 2019/12/19
    225. * @param fieldName 字段名
    226. * @param map 数据集合
    227. * @param clazz 类型
    228. * @return T 返回结果
    229. * @description 转换数据
    230. */
    231. @SuppressWarnings("unchecked")
    232. private <T> T getMapValueByKey(String fieldName, Map<String, Object> map, Class<T> clazz) {
    233. if(map.containsKey(fieldName)) return ((T) map.get(fieldName));
    234. return null;
    235. }
    236. }