poi導出word、excel

在實際的項目開發中,常常會有一些涉及到導入導出的文檔的功能。apache開源項目之一poi對此有很好的支持,對以前的使用作一些簡要的總結。html

1,導入jar

爲了保證對格式的兼容性,在項目的pom.xml添加這三個jar:git

<dependency>
             <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.13</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.13</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.13</version>
        </dependency>

 

2,生成文件、下載

通常咱們對導出的數據變化不會太大,因此考慮到重複使用,咱們能夠在服務端生成一個文件,在用戶再次導出時直接取這個文件下載便可,至關於一個緩存,固然若是服務端文件數過多須要定時任務或者shell去清理.. 很少囉嗦,下面開始貼代碼sql

/**
     * 生成考勤信息文檔
     * @param date 導出日期
     * @param type 1考勤統計總數word,2考勤詳情excle
     * @return
     * @throws IOException 
     */
    @RequestMapping(value="/export_message",method=RequestMethod.GET)
    public @ResponseBody CommonResponse export(@RequestParam String date,
                                                 @RequestParam Integer type,
                                                 @RequestParam Integer orgId,
                                                 @RequestParam String orgName,
                                               HttpServletResponse response,
                                               HttpServletRequest request) throws IOException{
        CommonResponse rsp = null;
        if (!StringUtil.isEmpty(date)) {
            String fileName = "";
            File file;
            if (type == 1) {
                fileName = date.trim()+ ".docx";
                file = new File(WORD+ fileName);
            }else{
                fileName = date.trim() + orgId + ".xls";
                file = new File(EXCEL + fileName);
            }
            
            if (file.exists()) {
                rsp = new CommonResponse(1, "exists",fileName);
            }else{
                //文件不存在,用poi生成
                int rs = messageService.exportMessage(DateUtil.str2Date(date),type,orgId,orgName);
                if (rs == 1){
                    rsp = new CommonResponse(0, "ok",fileName);
                }else{
                    rsp = new CommonResponse(-1, "error");
                }
            }
        }else{
            //參數錯誤
            rsp = new CommonResponse(-1,"error");
            logger.error("Fail to convert the parameters for export_message,date:{}", date);
        }
        return rsp;
    }
/**
     * 下載考勤信息文檔
     * @param response
     * @param request
     * @throws FileNotFoundException
     * @throws UnsupportedEncodingException
     */
    @RequestMapping(value="/down_info_file",method = RequestMethod.GET)
    public @ResponseBody void downFile(HttpServletResponse response,HttpServletRequest request) throws FileNotFoundException, UnsupportedEncodingException {
        
        String filePath,newFileName;
        String fileName = request.getParameter("fileName");
        
        //兼容性配置
        if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0){
            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");//firefox
        }else if(request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0){
            fileName = URLEncoder.encode(fileName, "UTF-8");//IE
        } 
        
        if (fileName.endsWith(".docx")) 
            filePath = WORD;
        else
            filePath = EXCEL;
        
        // 讀到流中
        InputStream inStream = new FileInputStream(filePath + fileName);
       
        if (fileName.endsWith(".docx"))
            newFileName = fileName.substring(0, 10) + "勤務上報數與排名統計.docx";
        else
            newFileName = fileName.substring(0, 10) + "勤務詳情統計.xls";
        
        // 設置輸出的格式
        response.reset();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(newFileName, "UTF-8")+ "\"");
        // 循環取出流中的數據
        byte[] b = new byte[1024];
        int len;
        try {
            while ((len = inStream.read(b)) > 0)
                response.getOutputStream().write(b, 0, len);
            inStream.close();
        } catch (IOException e) {
            logger.error("Download the document is failed,message:{}", e.getMessage());
        }
    }
@Override
    public int exportMessage(Date date,Integer type,Integer orgId,String orgName) {
        
        int rs = 0; 
       
        File wordfile = new File(WORD);
        File excelfile = new File(EXCEL);
        if (!wordfile.exists() || !excelfile.exists()) {  
            wordfile.mkdirs();// 目錄不存在的狀況下,建立目錄。
            excelfile.mkdirs();
        }  
        
        String exportExcel = EXCEL + DateUtil.date2Str(date) + orgId +".xls";
        String exportWord = WORD + DateUtil.date2Str(date) +".docx";
        if (type == 1) {
            try {
                List<MessageCount> listMc = new ArrayList<>();
                List<MessageTopUser> listMt = null;
                List<Organization> list = organizationService.findLessFour();
                for (int i = 0; i < list.size(); i++) {
                    Integer _orgId = list.get(i).getOrgId();
                    if (_orgId != 1) {
                        MessageCount mc = messageDao.findAllCountByOrgId(date, _orgId);
                        listMt = messageDao.findTopThree(date);
                        listMc.add(mc);
                    }
                }
                
                rs = exportWord(date, exportWord, listMc, listMt);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            List<Message> mes = messageDao.exportMessage(date,orgId);
            rs = exportExcle(date, mes, exportExcel, orgName);
        }
        
        return rs;
    }

3,word文檔流生成

public int exportWord(Date date,String exportPath, List<MessageCount> listMc, List<MessageTopUser> listMt) throws Exception{
        int result = 1;
        logger.debug("export excle start!,which date is : {}" + date);
        
        XWPFDocument doc = new XWPFDocument();//新建一個文檔  
        
        XWPFParagraph nav = doc.createParagraph(); 
        nav.setStyle("1"); //1級大綱
        XWPFRun runNav = nav.createRun(); 
        runNav.setBold(true); //加粗  
        runNav.setText("【塔式智能系統每日監測狀況通報】");
        
        String text = DateUtil.date2Str(date) + ",";
        int alarm = 0,news = 0,danger = 0,duty = 0,other = 0,police = 0,trail = 0;
        
        String allOutText = "";
        for (int i = 0; i < listMc.size(); i++) {
            MessageCount list = listMc.get(i);
            int getalarm = list.getAlarm().intValue();//一鍵報警
            int getnews = list.getNews().intValue();//動態
            int getdanger = list.getDanger().intValue();//隱患
            int getduty = list.getDuty().intValue();//勤務記錄
            int getother = list.getOther().intValue();//其餘
            int getpolice = list.getPolice().intValue();//警情
            int gettrail = list.getTrail().intValue();//線索
            
            alarm += getalarm;//一鍵報警
            news += getnews;//動態
            danger += getdanger;//隱患
            duty += getduty;//勤務記錄
            other += getother;//其餘
            police += getpolice;//警情
            trail += gettrail;//線索
            
            int count = getalarm + getnews + getdanger + getduty + getother + getpolice + gettrail;
            /*if (count != 0) {}*/
            String name = organizationService.findByOrgId(list.getOrgId()).getName().replace("中隊", "所");
            allOutText += i+1 +"." + name + count + "條。";
        }
        int allCount = alarm + news + danger + duty + other + police + trail;
        text += "發佈信息總數" + allCount + "條。";
        text += "其中動態" + news + "條,";
        text += "警情" + police + "條,";
        text += "線索" + trail + "條,";
        text += "隱患" + danger + "條,";
        text += "勤務記錄" + duty + "條,";
        text += "一鍵報警" + alarm + "條,";
        text += "其餘" + other + "條。";
        
        XWPFParagraph para = doc.createParagraph();
        XWPFRun run = para.createRun();
        run.setText(text);  
        run.setFontSize(8);
        run.setFontFamily("微軟雅黑");
        
        XWPFParagraph everyOrg = doc.createParagraph();
        XWPFRun ev = everyOrg.createRun();
        ev.setText(allOutText);
        ev.setFontSize(8);
        ev.setFontFamily("微軟雅黑");
        
        String topThree = "";
        for (int j = 0; j < listMt.size(); j++) {
            int total = listMt.get(j).getTotal().intValue();
            
            NumberFormat nt = NumberFormat.getPercentInstance();
            nt.setMinimumFractionDigits(2);//百分數保留兩位
            double divisor = (double)total/allCount;
            String percent = nt.format(divisor);
            logger.debug("The export word data for percent is "+percent);
            /*DecimalFormat df2  = new DecimalFormat("###.00");//保留兩位小數
            System.out.println("小數"+df2.format(p));*/
            topThree += j+1 + "." + listMt.get(j).getOrgName().replace("中隊", "所") + listMt.get(j).getUname() + ",發佈數" + total + "條,佔比" + percent + "; ";
        }
        
        XWPFParagraph topThreeP = doc.createParagraph();
        XWPFRun evp = topThreeP.createRun();
        evp.setText(topThree);
        evp.setFontSize(8);
        evp.setFontFamily("微軟雅黑");
        
        try {  
              FileOutputStream fout = new FileOutputStream(exportPath);  
              logger.debug("export excle end!");
                
              doc.write(fout);  //把doc輸出到輸出流  
                
              fout.close();  
          }  
          catch (Exception e){  
              result = 0;
              logger.error("export excle error!,{}",e.getLocalizedMessage());
          }
          
        return result;
    }

 

4,excel文檔流生成

@SuppressWarnings("deprecation")
    public int exportExcle(Date date,List<Message> mes,String exportPath,String orgName){
        int result = 1;
        logger.debug("Start export excle,which date is : {}" + date);
        HSSFWorkbook wb = new HSSFWorkbook();  
        HSSFSheet sheet = wb.createSheet(DateUtil.date2Str(date)); 
        HSSFRow rowMerging = sheet.createRow((short) 0);  
        HSSFRow row = sheet.createRow((short) 1);  
        
        //標題樣式
        HSSFCellStyle titleStyle = wb.createCellStyle();  
        titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 居中
        titleStyle.setBorderBottom((short)100);// 下邊框   
        titleStyle.setBorderTop((short)100);// 上邊框   
        HSSFFont titleFont = wb.createFont();
        titleFont.setFontHeightInPoints((short) 20);//設置字體大小
        titleFont.setFontName("宋體");
        titleFont.setColor(HSSFColor.RED.index);//紅字
        titleStyle.setFont(titleFont);
        
        //導航行樣式
        HSSFCellStyle navStyle = wb.createCellStyle();  
        navStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        navStyle.setBorderBottom((short)50);// 下邊框   
        navStyle.setBorderTop((short)50);// 上邊框   
        HSSFFont font = wb.createFont();
        font.setFontName("宋體");
        font.setFontHeightInPoints((short) 14);
        navStyle.setFont(font);
        
        sheet.addMergedRegion(new Region(0, (short) (0), 0,(short) (11))); //設置跨行, 四個參數分別是:起始行,起始列,結束行,結束列     
        //設置列寬,第一個參數表明列id(從0開始),第2個參數表明寬度值
        sheet.setColumnWidth(0, 6500);
        sheet.setColumnWidth(1, 4000);
        sheet.setColumnWidth(2, 8000);
        sheet.setColumnWidth(3, 5000);
        sheet.setColumnWidth(4, 4000);
        sheet.setColumnWidth(5, 4000);
        sheet.setColumnWidth(6, 4000);
        sheet.setColumnWidth(7, 4000);
        sheet.setColumnWidth(8, 4000);
        sheet.setColumnWidth(9, 4000);
        sheet.setColumnWidth(10, 4000);
        
        HSSFCell merging = rowMerging.createCell((short) 0);
        merging.setCellValue(DateUtil.date2Str(date) + orgName + "羣防羣治數據統計表");
        merging.setCellStyle(titleStyle);
        
        HSSFCell cell = row.createCell((short) 0);  
        cell.setCellValue("時間");  
        cell.setCellStyle(navStyle);  
        cell = row.createCell((short) 1);  
        cell.setCellValue("主題");  
        cell.setCellStyle(navStyle);  
        cell = row.createCell((short) 2);  
        cell.setCellValue("描述");  
        cell.setCellStyle(navStyle);  
        cell = row.createCell((short) 3);  
        cell.setCellValue("發送人");  
        cell.setCellStyle(navStyle);  
        cell = row.createCell((short) 4);  
        cell.setCellValue("機構ID");  
        cell.setCellStyle(navStyle); 
        cell = row.createCell((short) 5);  
        cell.setCellValue("機構名稱");  
        cell.setCellStyle(navStyle); 
        cell = row.createCell((short) 6);  
        cell.setCellValue("派出所ID");  
        cell.setCellStyle(navStyle);  
        cell = row.createCell((short) 7);  
        cell.setCellValue("所屬派出所");  
        cell.setCellStyle(navStyle);  
        cell = row.createCell((short) 8);  
        cell.setCellValue("發佈數");  
        cell.setCellStyle(navStyle);
        cell = row.createCell((short) 9);  
        cell.setCellValue("發佈率");  
        cell.setCellStyle(navStyle); 
        cell = row.createCell((short) 10);  
        cell.setCellValue("重複數");  
        cell.setCellStyle(navStyle); 
        cell = row.createCell((short) 11);  
        cell.setCellValue("不規範數");  
        cell.setCellStyle(navStyle); 
        
        //內容樣式
        HSSFCellStyle contentStyle = wb.createCellStyle();  
        contentStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        titleStyle.setBorderBottom((short)50);// 下邊框   
        titleStyle.setBorderTop((short)50);// 上邊框   
        HSSFFont fontcontent = wb.createFont();
        fontcontent.setFontName("宋體");
        fontcontent.setFontHeightInPoints((short) 12);
        navStyle.setFont(fontcontent);
        
        for (int i = 1; i <= mes.size(); i++)  
        {  
            row = sheet.createRow((int) i + 1);  
            Message rs = mes.get(i - 1);  
            
            HSSFCell cellContent = row.createCell((short) 0);  
            cellContent.setCellValue(DateUtil.toTimeString(rs.getSendTime()));  
            cellContent.setCellStyle(contentStyle);  
            cellContent = row.createCell((short) 1);  
            cellContent.setCellValue(rs.getMsgTypeName());  
            cellContent.setCellStyle(contentStyle);  
            cellContent = row.createCell((short) 2);  
            cellContent.setCellValue(StringUtil.isNull(rs.getContent())?"":rs.getContent());  
            cellContent.setCellStyle(contentStyle);  
            cellContent = row.createCell((short) 3);  
            cellContent.setCellValue(rs.getUname());  
            cellContent.setCellStyle(contentStyle);
            cellContent = row.createCell((short) 4);  
            cellContent.setCellValue(rs.getOrgId());  
            cellContent.setCellStyle(contentStyle);
            cellContent = row.createCell((short) 5);  
            cellContent.setCellValue(rs.getOrgName());  
            cellContent.setCellStyle(contentStyle);
            cellContent = row.createCell((short) 6);  
            int ancestors = rs.getAncestors().equals("") ? rs.getOrgId() : Integer.parseInt(rs.getAncestors());
            cellContent.setCellValue(ancestors);  
            cellContent.setCellStyle(contentStyle);
        }  
        
        try  
        {  
            FileOutputStream fout = new FileOutputStream(exportPath);  
            logger.debug("export excle end!");
            
            wb.write(fout);  
            
            fout.close();  
        }  
        catch (Exception e)  
        {  
            result = 0;
            logger.error("export excle error!,{}",e.getLocalizedMessage());
        }  
        return result;
    }

5,總結

其實導出是很簡單的,貼上代碼後基本上意思就出來了,無非就是經過使用XWPFDocument、HSSFWorkbook這兩個類,set相關屬性值,數據經過sql從數據庫裏讀取數據作一些相關的循環邏輯,再經過文檔流的形式反饋給客戶端。可能相對來講導入會比較麻煩,首先是從服務端下載一個模板,而後再根據模板填入數據上傳到服務器,這個時候須要作大量的驗證處理,再反饋給客戶有一個預覽界面等等,思路大體是這樣,後續再整理excel導入。shell

 

poi相關屬性參考:http://poi.apache.org/數據庫

各jar包做用參考:http://www.07net01.com/2014/09/63956.htmlapache

相關文章
相關標籤/搜索