基於SpringBoot框架管理Excel和PDF檔案型別
一、文件型別簡介
1、Excel文件
Excel一款電子表格軟體。直觀的介面、出色的計算功能和圖表工具,在系統開發中,經常用來把資料轉存到Excel檔案,或者Excel資料匯入系統中,這就涉及資料轉換問題。
2、PDF文件
PDF是可移植文件格式,是一種電子檔案格式,具有許多其他電子文件格式無法相比的優點。PDF檔案格式可以將文字、字型、格式、顏色及獨立於裝置和解析度的圖形影象等封裝在一個檔案中。該格式檔案還可以包含超文字連結、聲音和動態影像等電子資訊,支援特長檔案,整合度和安全可靠性都較高。
二、Excel檔案管理
1、POI依賴
Apache POI是Apache軟體基金會的開源類庫,POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。
<!-- Excel 依賴 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <!-- 2007及更高版本 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency>
2、檔案讀取
public static List<List<Object>> readExcel(String path) throws Exception { File file = new File(path) ; List<List<Object>> list = new LinkedList<>(); XSSFWorkbook xwb = new XSSFWorkbook(new FileInputStream(file)); // 讀取 Sheet1 表格內容 XSSFSheet sheet = xwb.getSheetAt(0); // 讀取行數:不讀取Excel表頭 for (int i = (sheet.getFirstRowNum()+1); i <= (sheet.getPhysicalNumberOfRows()-1); i++) { XSSFRow row = sheet.getRow(i); if (row == null) { continue; } List<Object> linked = new LinkedList<>(); for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) { XSSFCell cell = row.getCell(j); if (cell == null) { continue; } Object value ; // 這裡需根據實際業務情況處理 switch (cell.getCellType()) { case XSSFCell.CELL_TYPE_NUMERIC: //處理數值帶{.0}問題 value = Double.valueOf(String.valueOf(cell)).longValue() ; break; default: value = cell.toString(); } linked.add(value); } if (linked.size()!= 0) { list.add(linked); } } return list; }
3、檔案建立
public static void createExcel(String excelName,String[] headList,List<List<Object>> dataList) throws Exception { // 建立 Excel 工作簿 XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet(); // 建立表頭 XSSFRow row = sheet.createRow(0); for (int i = 0; i < headList.length; i++) { XSSFCell cell = row.createCell(i); cell.setCellType(XSSFCell.CELL_TYPE_STRING); cell.setCellValue(headList[i]); } //新增資料 for (int line = 0; line < dataList.size(); line++) { XSSFRow rowData = sheet.createRow(line+1); List<Object> data = dataList.get(line); for (int j = 0; j < headList.length; j++) { XSSFCell cell = rowData.createCell(j); cell.setCellType(XSSFCell.CELL_TYPE_STRING); cell.setCellValue((data.get(j)).toString()); } } FileOutputStream fos = new FileOutputStream(excelName); workbook.write(fos); fos.flush(); fos.close(); }
4、檔案匯出
public static void exportExcel(String[] headList,List<List<Object>> dataList,OutputStream outputStream) throws Exception { // 建立 Excel 工作簿 XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet(); // 建立表頭 XSSFRow row = sheet.createRow(0); for (int i = 0; i < headList.length; i++) { XSSFCell cell = row.createCell(i); cell.setCellType(XSSFCell.CELL_TYPE_STRING); cell.setCellValue(headList[i]); } //新增資料 for (int line = 0; line < dataList.size(); line++) { XSSFRow rowData = sheet.createRow(line+1); List<Object> data = dataList.get(line); for (int j = 0; j < headList.length; j++) { XSSFCell cell = rowData.createCell(j); cell.setCellType(XSSFCell.CELL_TYPE_STRING); cell.setCellValue((data.get(j)).toString()); } } workbook.write(outputStream); outputStream.flush(); outputStream.close(); }
5、檔案匯出介面
@RestController public class ExcelWeb { @RequestMapping("/web/outExcel") public void outExcel (HttpServletResponse response) throws Exception { String exportName = "2020-01-user-data" ; response.setContentType("application/vnd.ms-excel"); response.addHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(exportName,"UTF-8") + ".xlsx"); List<List<Object>> dataList = ExcelUtil.readExcel("F:\\file-type\\user-excel.xlsx") ; String[] headList = new String[]{"使用者ID","使用者名稱","手機號"} ; ExcelUtil.exportExcel(headList,dataList,response.getOutputStream()) ; } }
三、PDF檔案管理
1、IText依賴
iText是一種生成PDF報表的Java元件。通過在伺服器端使用頁面或API封裝生成PDF報表,客戶端可以通過超連結直接顯示或下載到本地,在系統開發中通常用來生成比較正式的報告或者合同類的電子文件。
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.11</version> </dependency> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.11</version> </dependency>
2、API二次封裝
首先對於Itext提供的API做一下表格、段落、圖片等基礎樣式的二次封裝,可以更好的適配業務。
public class PdfFontUtil { private PdfFontUtil(){} /** * 段落樣式獲取 */ public static Paragraph getParagraph (String content,Font font,Integer alignment){ Paragraph paragraph = new Paragraph(content,font) ; if (alignment != null && alignment >= 0){ paragraph.setAlignment(alignment); } return paragraph ; } /** * 圖片樣式 */ public static Image getImage (String imgPath,float width,float height) throws Exception { Image image = Image.getInstance(imgPath); image.setAlignment(Image.MIDDLE); if (width > 0 && height > 0){ image.scaleAbsolute(width,height); } return image ; } /** * 表格生成 */ public static PdfPTable getPdfPTable01 (int numColumns,float totalWidth) throws Exception { // 表格處理 PdfPTable table = new PdfPTable(numColumns); // 設定表格寬度比例為%100 table.setWidthPercentage(100); // 設定寬度:寬度平均 table.setTotalWidth(totalWidth); // 鎖住寬度 table.setLockedWidth(true); // 設定表格上面空白寬度 table.setSpacingBefore(10f); // 設定表格下面空白寬度 table.setSpacingAfter(10f); // 設定表格預設為無邊框 table.getDefaultCell().setBorder(0); table.setPaddingTop(50); table.setSplitLate(false); return table ; } /** * 表格內容 */ public static PdfPCell getPdfPCell (Phrase phrase){ return new PdfPCell (phrase) ; } /** * 表格內容帶樣式 */ public static void addTableCell (PdfPTable dataTable,List<String> cellList){ for (String content:cellList) { dataTable.addCell(getParagraph(content,font,-1)); } } }
3、生成PDF檔案
這裡基於上面的工具類,畫一個PDF頁面作為參考。
public class PdfPage01 { // 基礎配置 private static String PDF_SITE = "F:\\file-type\\PDF頁面2020-01-15.pdf" ; private static String FONT = "C:/Windows/Fonts/simhei.ttf"; private static String PAGE_TITLE = "PDF資料匯出報告" ; // 基礎樣式 private static Font TITLE_FONT = FontFactory.getFont(FONT,BaseFont.IDENTITY_H,20,Font.BOLD); private static Font NODE_FONT = FontFactory.getFont(FONT,15,Font.BOLD); private static Font BLOCK_FONT = FontFactory.getFont(FONT,13,Font.BOLD,BaseColor.BLACK); private static Font INFO_FONT = FontFactory.getFont(FONT,12,Font.NORMAL,BaseColor.BLACK); private static Font CONTENT_FONT = FontFactory.getFont(FONT,BaseFont.NOT_EMBEDDED); private static void createPdfPage () throws Exception { // 建立文件 Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document,new FileOutputStream(PDF_SITE)); document.open(); // 報告標題 document.add(PdfFontUtil.getParagraph(PAGE_TITLE,TITLE_FONT,1)) ; document.add(PdfFontUtil.getParagraph("\n商戶名稱:XXX科技有限公司",INFO_FONT,-1)) ; document.add(PdfFontUtil.getParagraph("\n生成時間:2020-01-15\n\n",-1)) ; // 報告內容 // 段落標題 + 報表圖 document.add(PdfFontUtil.getParagraph("城市資料分佈統計",NODE_FONT,-1)) ; document.add(PdfFontUtil.getParagraph("\n· 視覺化圖表\n\n",BLOCK_FONT,-1)) ; // 設定圖片寬高 float documentWidth = document.getPageSize().getWidth() - document.leftMargin() - document.rightMargin(); float documentHeight = documentWidth / 580 * 320; document.add(PdfFontUtil.getImage("F:\\file-type\\myChart.jpg",documentWidth-80,documentHeight-80)) ; // 資料表格 document.add(PdfFontUtil.getParagraph("\n· 資料詳情\n\n",-1)) ; PdfPTable dataTable = PdfFontUtil.getPdfPTable01(4,400) ; // 設定表格 List<String> tableHeadList = tableHead () ; List<List<String>> tableDataList = getTableData () ; PdfFontUtil.addTableCell(dataTable,CONTENT_FONT,tableHeadList); for (List<String> tableData : tableDataList) { PdfFontUtil.addTableCell(dataTable,tableData); } document.add(dataTable); document.add(PdfFontUtil.getParagraph("\n· 報表描述\n\n",-1)) ; document.add(PdfFontUtil.getParagraph("資料報告可以監控每天的推廣情況," + "可以針對不同的資料表現進行分析,以提升推廣效果。",-1)) ; document.newPage() ; document.close(); writer.close(); } private static List<List<String>> getTableData (){ List<List<String>> tableDataList = new ArrayList<>() ; for (int i = 0 ; i < 3 ; i++){ List<String> tableData = new ArrayList<>() ; tableData.add("浙江"+i) ; tableData.add("杭州"+i) ; tableData.add("276"+i) ; tableData.add("33.3%") ; tableDataList.add(tableData) ; } return tableDataList ; } private static List<String> tableHead (){ List<String> tableHeadList = new ArrayList<>() ; tableHeadList.add("省份") ; tableHeadList.add("城市") ; tableHeadList.add("數量") ; tableHeadList.add("百分比") ; return tableHeadList ; } public static void main(String[] args) throws Exception { createPdfPage () ; } }
4、頁面效果
四、網頁轉PDF
1、頁面Jar包依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
2、編寫頁面樣式
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"/> <title>Title</title> <style> body{font-family:SimSun;} </style> </head> <body> 專案資訊:<br/> 名稱:${name}<br/> 作者:${author}<br/><br/> <img src="https://img2018.cnblogs.com/blog/1691717/201906/1691717-20190603213911854-1098366582.jpg"/> <br/> </body> </html>
3、核心配置類
public class PageConfig { private static final String DEST = "F:\\file-type\\HTML頁面2020-01-15.pdf"; private static final String HTML = "/pdf_page_one.html"; private static final String FONT = "C:/Windows/Fonts/simsun.ttc"; private static Configuration freemarkerCfg = null ; static { freemarkerCfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); //freemarker的模板目錄 try { String path = "TODO:模板路徑{自定義}" ; freemarkerCfg.setDirectoryForTemplateLoading(new File(path)); } catch (IOException e) { e.printStackTrace(); } } /** * 建立文件 */ private static void createPdf(String content,String dest) throws Exception { Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document,new FileOutputStream(dest)); document.open(); XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS); fontImp.register(FONT); XMLWorkerHelper.getInstance().parseXHtml(writer,document,new ByteArrayInputStream(content.getBytes()),null,Charset.forName("UTF-8"),fontImp); document.close(); } /** * 頁面渲染 */ private static String freeMarkerRender(Map<String,Object> data,String htmlTmp) throws Exception { Writer out = new StringWriter(); Template template = freemarkerCfg.getTemplate(htmlTmp,"UTF-8"); template.process(data,out); out.flush(); out.close(); return out.toString(); } /** * 方法入口 */ public static void main(String[] args) throws Exception { Map<String,Object> data = new HashMap<> (); data.put("name","smile"); data.put("author","知了") ; String content = PageConfig.freeMarkerRender(data,HTML); PageConfig.createPdf(content,DEST); } }
4、轉換效果圖
五、原始碼地址
文中涉及檔案型別,在該章節原始碼ware18-file-parent/case-file-type目錄下。
GitHub·地址
https://github.com/cicadasmile/middle-ware-parent
GitEE·地址
https://gitee.com/cicadasmile/middle-ware-parent
總結
以上所述是小編給大家介紹的基於SpringBoot框架管理Excel和PDF檔案型別,希望對大家有所幫助!