網(wǎng)站開發(fā)程序員 工資百度云怎么找資源
目錄
項目需求
后端接口實現(xiàn)
1、引入poi依賴
2、代碼編寫
1、controller
2、service層
測試出現(xiàn)的bug
小結(jié)
項目需求
前端需要上傳pptx文件,后端保存為圖片,并將圖片地址保存數(shù)據(jù)庫,最后大屏展示時顯示之前上傳的pptx的圖片。需求看上去是簡單的,簡單聊一下,不管是使用vue的elementui還是傳統(tǒng)的layui都有很好的實現(xiàn)組件,這里我們重點不在前端,所以不去細說,感興趣的同學(xué)可以了解一下。
后端接口實現(xiàn)
1、引入poi依賴
這里我使用的是最新的依賴,大家想要穩(wěn)定一點可以用4.1.2的版本
<!-- excel解析工具 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>5.2.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>ooxml-schemas</artifactId><version>1.4</version></dependency>
2、代碼編寫
一般工作中,后端都是提供接口給前端訪問的,項目會有一定的分層
1、controller
我們主要用來接受參數(shù),然后把參數(shù)帶到service層去處理業(yè)務(wù)邏輯就行
這里我們需要接受的前端參數(shù)有2個:
MultipartFile:pptx文件對象
代碼示例:
@ResponseBody @RequestMapping("/admin/pheno/material/caseContentPhotoUpload")public ResultJson caseContentPhotoUpload(MultipartFile file, HttpServletRequest request) {return ResultJson.build(pheContentService.caseContentPhotoUpload(file,request));}
2、service層
實際的業(yè)務(wù)代碼編寫,代碼邏輯是比較簡單的,先獲取文件的輸入流,將文件輸入流轉(zhuǎn)化為xmlslideshow()對象,這個就是poi的處理pptx文件的工具包了,在里面循環(huán)操作每一張pptx。pptx文件也就是xml文件,所以是用這個處理的,然后就是保存圖片了,思路就是建一張畫布,將文件畫上去,最后保存到對應(yīng)路徑,本地數(shù)據(jù)庫啥的。非常簡單。IMAGE_SCALE 是一個常量,我給的是8,最后記得關(guān)閉不用的對象,回收一下內(nèi)存。
public ResultService caseContentPhotoUpload(MultipartFile file, HttpServletRequest request) {String serverPath=request.getSession().getServletContext().getRealPath("/");ArrayList<Object> outPathUrlList = new ArrayList<>();InputStream is = null;XMLSlideShow ppt = null;try {is = file.getInputStream();ppt =new XMLSlideShow(is);Dimension pgSize = ppt.getPageSize();for (XSLFSlide slide : ppt.getSlides()) {for(XSLFShape shape : slide.getShapes()){if(shape instanceof XSLFTextShape) {XSLFTextShape tsh = (XSLFTextShape)shape;for(XSLFTextParagraph p : tsh){for(XSLFTextRun r : p){r.setFontFamily("宋體");}}}}String url = toPNG(pgSize.width, pgSize.height, slide,serverPath,hrStaffSession);outPathUrlList.add(url);}} catch (IOException e) {log.debug("ppt轉(zhuǎn)換圖片失敗,{}"+ e.getMessage());throw new RuntimeException("ppt轉(zhuǎn)換圖片失敗" + e.getMessage());} finally {try {if (is != null) {is.close();}} catch (IOException e) {e.printStackTrace();}try {if (ppt != null) {ppt.close();}} catch (IOException e) {e.printStackTrace();}}return ResultService.buildSuccess(outPathUrlList);}
protected String toPNG(int pgWidth, int pgHeight, XSLFSlide slide, String serverPath, HrStaffSession hrStaffSession) throws IOException {int imageWidth = (int) Math.floor(IMAGE_SCALE * pgWidth);int imageHeight = (int) Math.floor(IMAGE_SCALE * pgHeight);ResultService resultService =null;BufferedImage img = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);Graphics2D graphics = img.createGraphics();graphics.setPaint(Color.white);graphics.fill(new Rectangle2D.Float(0, 0, pgWidth, pgHeight));graphics.scale(IMAGE_SCALE, IMAGE_SCALE);slide.draw(graphics);ByteArrayOutputStream bos = new ByteArrayOutputStream();try {bos = new ByteArrayOutputStream();ImageIO.write(img, "png", bos);InputStream input = new ByteArrayInputStream(bos.toByteArray());MultipartFile multipartFile = getMultipartFile(input,"ppt圖片.png");input.close();resultService = fileService.fileUpload(multipartFile, serverPath, hrStaffSession);} finally {bos.close();}SystemFileVO systemFileVO=(SystemFileVO)resultService.getObject();return systemFileVO.getThumbPath();}
測試出現(xiàn)的bug
不知道是poi對于pptx做的兼容不好還是啥原因,總之有很多的問題
1、文字問題,pptx使用的都是微軟雅黑,但是轉(zhuǎn)為圖片時,文字會有溢出和下墜的變化,
所以我從4.1.2的包切到了新版本的5.2.0,解決了文字的溢出問題,然后我將微軟雅黑統(tǒng)一設(shè)置成宋體,在window上是解決了,但是在linux上展現(xiàn)效果又有一定的差異,總的來說是解決了。
2、段落的首行縮進混亂,設(shè)置了首行縮進,但是縮進去了一行的最后面
最后只能不要這個樣式,去手動添加空格
3、一些圖標(biāo)無法讀取,當(dāng)圖標(biāo)是組合式也就是拼接的時候,會出現(xiàn)讀取不了的情況,也只能在寫pptx的時候規(guī)避一下
4、在不同操作系統(tǒng)上展現(xiàn)效果有細微區(qū)別,測試也比較麻煩
。。。
小結(jié)
感覺在技術(shù)的選取上應(yīng)該再參考一下,是否poi是這個需求最好的處理對象,是不是還有更好的處理方式。