Java - Execl自定義導入、導出

1.需求:問卷星答 下圖框出區域,為用戶自定義字段問題及答案

在這里插入圖片描述

2.采用技術EasyExcel

模板所在位置如下
在這里插入圖片描述

/*** 導出模板** @param response*/
@Override
public void exportTemplate(HttpServletResponse response) throws IOException {ClassPathResource classPathResource = new ClassPathResource("templates/會員滿意度調研.xlsx");StreamUtils.copy(classPathResource.getInputStream(),response.getOutputStream());
}
3.監聽Listener繼承AnalysisEventListener
導入模板數據時,所用的監聽器
package com.huatek.frame.modules.survey.service.impl;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.ArrayList;
import java.util.Map;@Slf4j
public class SurveyImportMessageListener extends AnalysisEventListener<Object> {private final Logger logger = LoggerFactory.getLogger(this.getClass());private ArrayList<Object> datas = new ArrayList();/*** 表頭*/private Map<Integer, String> headMap;public SurveyImportMessageListener() {}public void invoke(Object data, AnalysisContext analysisContext) {this.datas.add(data);
}public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {this.headMap = headMap;
}public void doAfterAllAnalysed(AnalysisContext context) {
}public ArrayList<Object> getDatas() {return this.datas;
}
public Map<Integer, String> getHead() {return this.headMap;
}
}
4.導入問卷
/*** 導入問卷** @param file* @param localUser* @return*/
@Override
public List<String> importSurvey(MultipartFile file, String surveyMainId,UserAuthProfileInfo localUser) {List<String> errorList = new ArrayList<>();try {SurveyImportMessageListener listener = new SurveyImportMessageListener();EasyExcel.read(file.getInputStream(), listener).sheet().doRead();ArrayList datas = listener.getDatas();Map<Integer, String> head = listener.getHead();LinkedList<SurveyProblemAnswerVO> surveyProblemAnswerVOS = new LinkedList();LinkedList<SurveyProblemAnswerItemVO> surveyProblemAnswerItemVOS = new LinkedList();head.forEach((key,value)->{//存儲問題if(key >= 6){SurveyProblemAnswerItemVO item = new SurveyProblemAnswerItemVO();item.setProblem(value);item.setSortBy(key);surveyProblemAnswerItemVOS.add(item);}});for (Object data : datas) {SurveyProblemAnswerVO survey = new SurveyProblemAnswerVO();List<SurveyProblemAnswerItemVO> items = BeanListUtils.copyListProperties(surveyProblemAnswerItemVOS, SurveyProblemAnswerItemVO::new);survey.setSurveyMainId(surveyMainId);((LinkedHashMap<Integer, String>) data).forEach((key,value)->{if(key == 1) survey.setSubmitTime(DateUtil.parse(value,"yyyy/MM/dd HH:mm:ss"));if(key == 2) survey.setUseTime(value);if(key == 3) survey.setSource(value);if(key == 4) survey.setSourceInfo(value);if(key == 5) survey.setSourceIp(value);//存儲問題答案if(key >= 6){SurveyProblemAnswerItemVO item = items.get(key-6);item.setAnswer(value);}});survey.setItemVOList(items);surveyProblemAnswerVOS.add(survey);}log.info("導入問答信息:{}", JSONArray.toJSONString(surveyProblemAnswerVOS));for (SurveyProblemAnswerVO surveyProblemAnswerVO : surveyProblemAnswerVOS) {SurveyMain surveyMain = surveyMainMapper.selectById(surveyMainId);if(surveyMain.getImportTime() == null){surveyMain.setImportTime(new Date());HttpServletRequest request = RequestHolder.getHttpServletRequest();JSONObject jsonObject = securityUser.currentUser(securityUser.getToken(request));surveyMain.setImportBy(jsonObject.get("userName").toString());surveyMainMapper.updateById(surveyMain);}SurveyProblemAnswer surveyProblemAnswer = new SurveyProblemAnswer();BeanUtils.copyProperties(surveyProblemAnswerVO,surveyProblemAnswer);surveyProblemAnswerService.saveOrUpdate(surveyProblemAnswer);List<SurveyProblemAnswerItemVO> itemVOList = surveyProblemAnswerVO.getItemVOList();itemVOList.forEach(item->item.setSurveyId(surveyProblemAnswer.getId()));List<SurveyProblemAnswerItem> surveyProblemAnswerItems = BeanListUtils.copyListProperties(itemVOList, SurveyProblemAnswerItem::new);surveyProblemAnswerItemService.saveOrUpdateBatch(surveyProblemAnswerItems);}} catch(Exception e){log.error("導入問卷異常",e);}return errorList;
}
5.根據模板導出數據
@Override
public void exportExcel(SurveyProblemAnswerVO vo, HttpServletResponse response) throws IOException {List<SurveyProblemAnswer> surveyProblemAnswers = surveyProblemAnswerMapper.selectList(new LambdaQueryWrapper<SurveyProblemAnswer>().eq(SurveyProblemAnswer::getSurveyMainId, vo.getId()));List<String> surveyIds = surveyProblemAnswers.stream().map(item -> item.getId()).collect(Collectors.toList());List<SurveyProblemAnswerItem> surveyProblemAnswerItems = surveyProblemAnswerItemMapper.selectList(new LambdaQueryWrapper<SurveyProblemAnswerItem>().in(SurveyProblemAnswerItem::getSurveyId, surveyIds));LinkedList<List<String>> head = new LinkedList<>();head.add(CollectionUtil.newArrayList("序號"));head.add(CollectionUtil.newArrayList( "提交答卷時間"));head.add(CollectionUtil.newArrayList( "所用時間"));head.add(CollectionUtil.newArrayList( "來源"));head.add(CollectionUtil.newArrayList( "來源詳情"));head.add(CollectionUtil.newArrayList( "來源IP"));List<SurveyProblemAnswerItem>  problemItems = surveyProblemAnswerItems.stream().filter(item -> item.getSurveyId().equals(surveyProblemAnswers.get(0).getId())).sorted(Comparator.comparing(SurveyProblemAnswerItem::getSortBy)).collect(Collectors.toList());for (SurveyProblemAnswerItem item : problemItems) {head.add(CollectionUtil.newArrayList( item.getProblem()));}LinkedList<List<Object>> data = new LinkedList<>();int count = 0;for (SurveyProblemAnswer surveyProblemAnswer : surveyProblemAnswers) {List<Object> tmp = new ArrayList<>();tmp.add(++count);tmp.add(surveyProblemAnswer.getSubmitTime() == null ? "" : surveyProblemAnswer.getSubmitTime());tmp.add(surveyProblemAnswer.getUseTime() == null ? "":surveyProblemAnswer.getUseTime());tmp.add(surveyProblemAnswer.getSource() == null ? "":surveyProblemAnswer.getSource());tmp.add(surveyProblemAnswer.getSourceInfo() == null ? "":surveyProblemAnswer.getSourceInfo());tmp.add(surveyProblemAnswer.getSourceIp() == null ? "":surveyProblemAnswer.getSourceIp());List<SurveyProblemAnswerItem> items = surveyProblemAnswerItems.stream().filter(item -> item.getSurveyId().equals(surveyProblemAnswer.getId())).sorted(Comparator.comparing(SurveyProblemAnswerItem::getSortBy)).collect(Collectors.toList());for (SurveyProblemAnswerItem item : items) {if(StringUtils.isNotEmpty(item.getAnswer())){tmp.add(item.getAnswer());}else{tmp.add("");}}data.add(tmp);}EasyExcel.write(response.getOutputStream(),null).head(head).autoCloseStream(false).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("會員滿意度調研模板").doWrite(data);
}

以上均為實現類,具體接口可參照定義

結果如下:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/36428.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/36428.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/36428.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Metricbeat和Prometheus監控比較

Metricbeat和Prometheus是兩種常見的監控工具&#xff0c;它們都有收集和存儲系統和應用程序性能數據的功能&#xff0c;但它們的設計理念、實現方式和適用場景有所不同。以下是它們的相同點和不同點的詳細比較&#xff1a; 相同之處 數據收集&#xff1a; Metricbeat 和 Pro…

vue 使用 face-api.js 實現人臉識別

HTML 代碼如下 <div class="videoBox" id="videoBox"><video ref="videoPlayer" width="800" height="600" autoplay muted playsinline></video><canvas ref="overlay"></canvas>…

配置 Cmder 到鼠標右鍵

win Q 快捷鍵搜索 cmd&#xff0c;以管理員身份運行 在命令行輸入 cmder.exe /REGISTER ALL

OpenCloudOS開源的操作系統

OpenCloudOS 是一款開源的操作系統&#xff0c;致力于提供高性能、穩定和安全的操作系統環境&#xff0c;以滿足現代計算和應用程序的需求。它結合了現代操作系統設計的最新技術和實踐&#xff0c;為開發者和企業提供了一個強大的平臺。本文將詳細介紹 OpenCloudOS 的背景、特性…

品牌進行3D數字化轉型,有哪些優勢?

各行業都在經歷著從增量市場向存量市場的轉變&#xff0c;同時用戶的消費觀念也日趨成熟&#xff0c;更加注重產品的體驗和服務質量。 無論是線上購物平臺還是線下實體門店&#xff0c;提供個性化和增強體驗感的產品與服務已成為未來發展的核心驅動力&#xff0c;品牌轉型也迫…

SyncFolders文件備份—辦公人員必備

SyncFolders支持在兩個或多個文件夾之間同步文件&#xff0c;用戶可以將重要文件同步到多個位置&#xff0c;如備份硬盤、網絡共享文件夾或云存儲等。通過設定同步規則&#xff0c;可以自動備份和同步更新&#xff0c;減少手動操作的繁瑣&#xff0c;確保文件的安全和可訪問性。…

uniapp橫屏移動端卡片縮進輪播圖

uniapp橫屏移動端卡片縮進輪播圖 效果&#xff1a; 代碼&#xff1a; <!-- 簡單封裝輪播圖組件:swiperCard --> <template><swiper class"swiper" circular :indicator-dots"true" :autoplay"true" :interval"10000&quo…

標準庫STL

標準庫STL stringstreamvector自定義類型初始化為一個數 queue stringstream 頭文件sstream。格式化字符流 #include <iostream> #include <sstream> using namespace std; int main(){stringstream ss;// hex 以十六進制保存 oct是8進制ss <<89<<…

軟件必須要進行跨瀏覽器測試嗎?包括哪些內容和注意事項?

隨著互聯網的普及和發展&#xff0c;用戶對軟件的要求越來越高。無論是在臺式機、筆記本還是移動設備上&#xff0c;用戶都希望能夠以最好的體驗來使用軟件。然而&#xff0c;不同的瀏覽器在解析網頁的方式、支持的技術標準等方面存在差異&#xff0c;這就導致了同一個網頁在不…

fpga bitstream userid

fpga version register # xdc 文件 set_property BITSTREAM.CONFIG.USERID "0xDEADC0DE" [current_design] set_property BITSTREAM.CONFIG.USR_ACCESS 0x66669999 [current_design]ug908 在bit下載之后的property可以看到 &#xff0c;GUI里面Tools → Edit Devic…

QT項目實戰:拼圖小游戲

一、拼圖智益-經典游戲&#xff08;開發環境&#xff09; 1&#xff1a;操作系統&#xff1a;Windows 10 x64專業版。 2&#xff1a;開發工具&#xff1a;Qt 5.12.8。 二、拼圖智益-經典游戲&#xff08;功能模塊&#xff09; 1&#xff1a;功能模塊1&#xff1a;游戲啟動…

1.1電路模型

1.1電路模型 任何實際電路由以下三部分組成&#xff1a; ①提供電能的能源 – 電源 ②用電裝置 – 負載 ③傳輸電能的金屬連線 – 導線 實際電路完成的功能&#xff1a;主要有以下兩個方面&#xff1a; &#xff08;1&#xff09;進行能量的產生、傳輸和轉換。&#xff08;如…

flash申請內存失敗,導致老化問題解決

背景 在閃光燈初始化階段客制化了一個buffer&#xff0c;下發到kernel的閃光燈驅動中用于保存讀取閃光燈寄存器的值。功能測試都是正常的&#xff0c;但是一旦開始批量跑產線老化測試會有1/4500左右概率的后主攝拍照卡住。定位根因是閃光燈初始化失敗&#xff0c;進一步原因就…

Django實現博客標簽字符串拆分功能

在Django模板中&#xff0c;可以使用自定義的模板過濾器來實現字符串的拆分。以下是一個簡單的示例&#xff0c;演示如何根據特定的分隔符拆分字符串并在模板中顯示。 首先&#xff0c;在Django應用的templatetags目錄中&#xff0c;創建一個Python模塊&#xff0c;例如extras…

C++中的網絡協議和網絡框架TCP和HTTP

一.OSI七層網絡模型 即開放式系統互連。 一般都叫OSI參考模型&#xff0c;是ISO組織在1985年研究的網絡互連模型。該體系結構標準定義了網絡互連的七層框架&#xff08;物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層和應用層&#xff09;&#xff0c;即OSI開放系統互連…

牛筋面,一口難忘的勁道滋味

在眾多的平涼美食中&#xff0c;牛筋面以其獨特的口感和豐富的口味&#xff0c;贏得了無數食客的喜愛。牛筋面&#xff0c;這一名字就給人一種堅韌、有嚼勁的印象。它并非由牛筋制成&#xff0c;而是因其面條的口感如牛筋般勁道而得名。牛筋面的制作過程頗具巧思。選用優質的面…

sheng的學習筆記-AI-K均值算法

ai目錄&#xff1a;sheng的學習筆記-AI目錄-CSDN博客 需要學習前置知識&#xff1a;聚類&#xff0c;可參考 sheng的學習筆記-聚類(Clustering)-CSDN博客 目錄 什么是k均值算法 流程 偽代碼 數據集 偽代碼 代碼解釋 劃分示意圖 優化目標 隨機初始化 選擇聚類數…

工作目錄問題,明明有該文件卻import錯誤?

背景 最近在進行多模塊集成的時候&#xff0c;出現了import錯誤的現象&#xff0c;雖然直接用絕對目錄解決了&#xff0c;但是顯然不優雅&#xff0c;在復習了有關工作目錄的知識后&#xff0c;了解到了問題所在。故寫此博客&#xff0c;希望對讀者有所幫助。 場景說明 有兩…

Interposer, 基板,轉接板

2. 結構與材料 3. 應用領域 4. 總結 Interposer、基板和轉接板在電子封裝和連接技術中各自扮演著不同的角色,以下是對它們之間區別的清晰解釋: 1. 定義與功能 Interposer: 定義:Interposer是一種中介層技術,用于實現芯片之間的水平互連和垂直互連。功能:通常是一個薄型的…

鴻蒙期末項目(3)

服務器搭建完成之后&#xff0c;編寫了諸多api用于數據傳輸工作&#xff08;略&#xff09; 編寫完成之后&#xff0c;回到鴻蒙開發工具&#xff0c;開始編寫搜索頁面的代碼。 打開搜索頁面時&#xff0c;先會展示歷史搜索記錄&#xff08;如果有的話&#xff09;&#xff0c;…