日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

poi

發(fā)布時間:2024/6/21 综合教程 26 生活家
生活随笔 收集整理的這篇文章主要介紹了 poi 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

-----

這是導(dǎo)出時,容易出現(xiàn)的問題,后面說到

設(shè)置字符編碼:

Font font =wb.createFont();
font.setCharSet(font.ANSI_CHARSET);//注意這地方不能手寫數(shù)字,這是常量



開始正文

一、黑歷史

為什么要做excel打印:就是為了客戶需求,有的客戶習(xí)慣excel。

java操作excel主要分兩類:

1、(全方位操作用)poi大概就是:屬于apache的產(chǎn)品,操作microsoft excel word,ppt,visio等微軟旗下所有的工具,支持office所有版本。

但是在poi早期,當(dāng)時微軟產(chǎn)品都時OLE2結(jié)構(gòu)(底層就是2進制)文件,這是office2003以前;然而poi操作大數(shù)據(jù)時,就會有bug,然而jxl也是這種數(shù)據(jù)結(jié)構(gòu),但可以解決這問題,所以jxl當(dāng)時比office厲害。

從office2007開始,微軟就重新開發(fā)了office,底層使用OOXML結(jié)構(gòu),這種數(shù)據(jù)結(jié)構(gòu),可以操作大數(shù)據(jù),所以excel底層就是xml格式文件。

2、(一般導(dǎo)入導(dǎo)出數(shù)據(jù)時用)jxl時僅用來操作excel,并且僅支持2003以下版本,不支持2007,也僅僅時OLE2文檔結(jié)構(gòu)。

二、jar準(zhǔn)備

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

三、怎么使用(本質(zhì)就是將內(nèi)存中的數(shù)據(jù)通過流的方式寫到硬盤上)

  1、訓(xùn)練

第一節(jié)認(rèn)清:excel怎么創(chuàng)建表然后怎么寫內(nèi)容然后再保存文件

創(chuàng)建一個工作簿
創(chuàng)建一個工作表,默認(rèn)是3個工作表
定位哪一個行
定位哪一列
單元格寫內(nèi)容(這前面5步都是在內(nèi)存中進行的,不要被表面迷惑)
點擊保存(這將內(nèi)存中數(shù)據(jù)序列化到硬盤上)
關(guān)閉

第二節(jié):設(shè)置單元格內(nèi)容

Workbook wb =new HSSFWorkbook();
    Sheet sh = wb.createSheet();
    Row row = sh.createRow(1);
    Cell cell = row.createCell(1);
    cell.setCellValue("我是中國人");
    FileOutputStream op =new FileOutputStream("D:\B.xls");
    wb.write(op);執(zhí)行完這一步,內(nèi)容就寫到硬盤上,即B.xls創(chuàng)建了
    op.close(); 如果還沒執(zhí)行這一步,那么excel進程提示被占用,不能編輯。關(guān)閉流后,才可以操作excel

第三節(jié):設(shè)置樣式(這和設(shè)置內(nèi)容是不同的東西)--------重點

CellStyle cs=wb.createCellStyle();//注意這方法是工作簿的,單元格樣式,excel無論是合并還是什么的都是單元格,還有邊框,背景色等等都是樣式,所以樣式就是全局的
    Font font=wb.createFont();//創(chuàng)建字體,也只能工作簿擁有,是全局的,字體無論在哪一張工作表都是擁有工作簿提供的所有字體,所以這個方法只能是工作簿的
    font.setFontName("微軟雅黑");//設(shè)置字體
    font.setFontHeightInPoints((short)24);//設(shè)置字體高度值點數(shù),就是設(shè)置大小,點數(shù)相當(dāng)于單位-------注意的地方,也可以用setFontHeight,但單位不同,需要換算,所以統(tǒng)一用setFontHeightInPoints,
    cs.setFont(font);設(shè)置字體樣式
    cell.setCellStyle(cs);//設(shè)置單元格樣式
創(chuàng)建樣式對象-->創(chuàng)建字體對象-->設(shè)置字體對象各種樣式-->設(shè)置字體-->設(shè)置單元格樣式

第四節(jié):優(yōu)化代碼

為了避免重復(fù)new對象,造成內(nèi)存損失,可以引用利用(引用被利用,沒有被引用指向的對象會被垃圾回收期回收)java是一個引用同時間只能指向一個對象(不然虛擬機不知道調(diào)用那個對象),多個對象可以指向一個引用

A n = new Hero();

n = new Hero();//同一個引用garen指向新創(chuàng)建的對象,上面那個對象就會被垃圾回收機制回收(多個對象可以指向一個引用)

1設(shè)置單元格內(nèi)容再利用:

     row1 = sh.createRow(2); 再利用 row引用
     cell2 = row1.createCell(2);在利用cell引用
    cell2.setCellValue("woshizhongguoren ");

2設(shè)置樣式再利用(因為是全局的,所以會出現(xiàn)后者覆蓋前者,所以不能直接利用font,cs,)

所以必須font 和cs初始化

font= wb.createFont();再利用font引用
cs = wb.createCellStyle();再利用cs引用
font.setFontHeightInPoints((short)18);
font.setFontName("隸書");
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
cs.setFont(font);
cell.setCellStyle(cs);


以上代碼可以抽取出來:

excel 標(biāo)題樣式一般相同,內(nèi)容樣式一般相同,簡化代碼,每次調(diào)用方法前,初始化對象

Workbook wb =new HSSFWorkbook();
    Sheet sh = wb.createSheet();
    
    Row row = sh.createRow(1);
    Cell cell = row.createCell(1);
    cell.setCellValue("我是中國人");
    CellStyle cs=wb.createCellStyle();        
    Font font=wb.createFont();
    this.getCellStylefont(font, cs, cell);
    
    
   初始化: 
    row = sh.createRow(2);
    cell = row.createCell(2);
    cell.setCellValue("woshizhongguoren ");
     font= wb.createFont();
     cs = wb.createCellStyle();
     this.getCellStyletext(font, cs, cell);
這是excel標(biāo)題
public CellStyle getCellStyleTitle(Font font,CellStyle cs,Cell cell){ font.setFontHeightInPoints((short)18); font.setFontName("隸書"); font.setBoldweight(Font.BOLDWEIGHT_BOLD); cs.setFont(font); cell.setCellStyle(cs); return cs; }
這是excel 內(nèi)容
public CellStyle getCellStyletext(Font font,CellStyle cs,Cell cell){ font.setFontName("微軟雅黑"); font.setFontHeightInPoints((short)85); cs.setFont(font); cell.setCellStyle(cs); return cs; }

  2、項目運用

打印一張出貨表:

日期處理可以數(shù)據(jù)庫處理,也可以在poi處理

加個鏈接,添加打印按鈕,根據(jù)日期,后臺通過sql查詢,返回list集合,通過循環(huán)遍歷導(dǎo)出一張excel表

添加單元格數(shù)據(jù):

List<OutProduct> outProductList = outProductService.find(paraMap);
        HSSFWorkbook wb =new HSSFWorkbook();
        HSSFSheet sh = wb.createSheet();
        int i=1;  //定義列起始索引
        int j=0;//定義行起始索引
        HSSFRow cr ;//聲明行局部變量
        HSSFCell cc;//聲明單元格局部變量
        String[] arr=new String[]{"客戶","訂單號","貨號","數(shù)量","工廠","工廠交期","船期","貿(mào)易條款"};  //標(biāo)題欄
        cr=sh.createRow(j++);
        for (String val : arr) {
            cc=cr.createCell(i++);
            cc.setCellValue(val);
        }
        for(OutProduct op: outProductList){                                                    //數(shù)據(jù)欄
            i=1;  //初始化列起始索引
            cr=sh.createRow(j++); j++就是j先賦值,然后再自增
            cc=cr.createCell(i++);
            String customName = op.getCustomName();
            cc.setCellValue(customName);
            
            cc=cr.createCell(i++);
            String contractNo = op.getContractNo();
            cc.setCellValue(contractNo);
            
            cc=cr.createCell(i++);
            String productNo = op.getProductNo();
            cc.setCellValue(productNo);
            
            cc=cr.createCell(i++);
            String boxNum = op.getBoxNum();
            cc.setCellValue(boxNum);
            
            cc=cr.createCell(i++);
            String factoryName = op.getFactoryName();
            cc.setCellValue(factoryName);
            
            cc=cr.createCell(i++);
            String deliveryPeriod = op.getDeliveryPeriod();
            cc.setCellValue(deliveryPeriod);
            
            cc=cr.createCell(i++);
            String shipTime = op.getShipTime();
            cc.setCellValue(shipTime);
            
            cc=cr.createCell(i++);
            String tradeTerms = op.getTradeTerms();
            cc.setCellValue(tradeTerms);
            
            
        }
        OutputStream out =new FileOutputStream("d://a.xls");
        wb.write(out);
        out.close();

這里可以看出j++好處,中間插入一個大標(biāo)題,下面的內(nèi)容自動往下移動

這部分仍是添加單元格內(nèi)容:大標(biāo)題是合并單元格,

所以表格的合并單元格方法,指定4個參數(shù),起始行,結(jié)束行,起始列,結(jié)束列

然后怎么做到“2018年8月份出貨表”,時間是動態(tài)的,前臺傳過來的,

replaceFirst成功則返回替換的字符串,失敗則返回原始字符串,所以要先進行-0替換,大范圍替換,沒有0則返回原始字符串,然后小范圍-替換成年

    sh.addMergedRegion(new CellRangeAddress(0, 0, 1, 8)); //合并單元格默認(rèn)是設(shè)置在區(qū)域的第一行第一列
        cr=sh.createRow(j++);
        cc=cr.createCell(1);
        cc.setCellValue(pdate.replaceFirst("-0", "年").replaceFirst("-", "年")+"月份出貨表");

添加單元格樣式:

設(shè)置字體和樣式:

這兩個對象都是workbook對象創(chuàng)建的,字體包含在樣式中

HSSFCellStyle nstyle = wb.createCellStyle();
        HSSFFont nfont = wb.createFont();
        bigTitle(wb, nstyle, nfont);
        cc.setCellStyle(nstyle);

行高是行對象創(chuàng)建,

cr.setHeightInPoints(36);

字體加粗是字體對象

單元格內(nèi)容居中這是樣式對象,樣式CellStyle中有橫向和豎向常量

public void bigTitle(Workbook wb,CellStyle nstyle,Font nfont){
        nfont.setFontHeightInPoints((short)16);
        nfont.setFontName("宋體");
        nstyle.setFont(nfont);
        nfont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//加粗,這是常量,是HSSFFont類中的常量

nstyle.setAlignment(CellStyle.ALIGN_CENTER);橫向居中
nstyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);縱向居中

    }
	設(shè)置邊框
		nstyle.setBorderBottom(CellStyle.BORDER_THIN);
		nstyle.setBorderLeft(CellStyle.BORDER_THIN);
		nstyle.setBorderRight(CellStyle.BORDER_THIN);
		nstyle.setBorderTop(CellStyle.BORDER_THIN);

  分大標(biāo)題 標(biāo)題 正文設(shè)置樣式,每次設(shè)置樣式錢需要初始化,

     初始化  nstyle = wb.createCellStyle();
		nfont = wb.createFont();
		

  

public void bigTitle(Workbook wb,CellStyle nstyle,Font nfont){
        nfont.setFontHeightInPoints((short)16);
        nfont.setFontName("宋體");
        nfont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        nstyle.setAlignment(CellStyle.ALIGN_CENTER);
        nstyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        nstyle.setFont(nfont);
        
    }
    public CellStyle title(Workbook wb,CellStyle nstyle,Font nfont){
        nfont.setFontHeightInPoints((short)12);
        nfont.setFontName("黑體");
        
        nstyle.setAlignment(CellStyle.ALIGN_CENTER);
        nstyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        
        nstyle.setBorderBottom(CellStyle.BORDER_THIN);
        nstyle.setBorderLeft(CellStyle.BORDER_THIN);
        nstyle.setBorderRight(CellStyle.BORDER_THIN);
        nstyle.setBorderTop(CellStyle.BORDER_THIN);
        nstyle.setFont(nfont);
        return nstyle;
        
    }
    public CellStyle text(Workbook wb,CellStyle nstyle,Font nfont){
        nfont.setFontHeightInPoints((short)10);
        nfont.setFontName("Times New Roman");
        nstyle.setAlignment(CellStyle.ALIGN_LEFT);
        nstyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        nstyle.setFont(nfont);
        return nstyle;
    }

列寬特殊,這是表對象的,sheet:通過源碼可以得出,需要乘以256,這是api bug

然而還是差那么一點點,這是poi一個bug,不能夠精確。所以經(jīng)過測試一般接近準(zhǔn)確*300,

a列是為了裝訂線的位置

打印時,不能在一頁顯示,可以設(shè)置橫向,拖到一頁,可以設(shè)置頁面方向

設(shè)置頁眉頁腳,設(shè)置重復(fù)標(biāo)題行


上面所說的都是下載,用戶體驗不好,項目中都是模板開發(fā),用戶需求變更,只要改變模板上的樣式,并且模板的樣式都是通過excel手動設(shè)置,不需要在代碼中設(shè)置,代碼中只要獲取一行模板樣式,后面的內(nèi)容全設(shè)置成模板樣式就可以了,

可以解決上面所有問題。不然每次輸出的文件在服務(wù)器端,用戶沒法看,

項目上傳下載 用工具類


        ByteArrayOutputStream bo=new ByteArrayOutputStream();
        wb.write(bo);
        
        DownloadUtil du=new DownloadUtil();
        du.download(bo, response, "出貨表.xls");
工具類: * @param byteArrayOutputStream 將文件內(nèi)容寫入ByteArrayOutputStream
     * @param response HttpServletResponse    寫入response
     * @param returnName 返回的文件名
     */
    public void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException{
        response.setContentType("application/octet-stream;charset=utf-8");
        returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1"));            //保存的文件名,必須和頁面編碼一致,否則亂碼
        response.addHeader("Content-Disposition",   "attachment;filename=" + returnName);  
        response.setContentLength(byteArrayOutputStream.size());
        
        ServletOutputStream outputstream = response.getOutputStream();    //取得輸出流
        byteArrayOutputStream.writeTo(outputstream);                    //寫到輸出流
        byteArrayOutputStream.close();                                    //關(guān)閉
        outputstream.flush();                                            //刷數(shù)據(jù)
    }

通過模板開發(fā):下面是模板

主要步驟:讀取服務(wù)器上的模板文件到內(nèi)存中,然后在內(nèi)存中對內(nèi)存中的模板進行大標(biāo)題:設(shè)置動態(tài)值,標(biāo)題:不用管了,用內(nèi)存中模板標(biāo)題,內(nèi)容上:設(shè)置內(nèi)容、樣式和模板一行內(nèi)容樣式一樣

    @RequestMapping("/cargo/outproduct/outProductPrint.action")
    public void print(String inputDate, HttpServletResponse response) throws FileNotFoundException, IOException, ParseException{
        /*
         * 操作步驟:
         * 1、獲取數(shù)據(jù)
         * 2、POI寫數(shù)據(jù)到文件
         */
        List<OutProduct> oList = outProductService.findOutProduct(inputDate+"%");
        
        Workbook wb = new HSSFWorkbook(new FileInputStream(new File("c:\tFACTORY.xls")));                //打開模板文件
        Sheet sheet = wb.getSheetAt(0);                        //打開第一個工作表
        Row nRow = null;
        Cell nCell = null;
        int rowNo = 2;                                        //行號
        int colNo = 1;                                        //列號
        
        //處理標(biāo)題
        nRow = sheet.getRow(0);                                //獲得行對象
        nCell = nRow.getCell(1);                            //獲得單元格對象
        nCell.setCellValue(inputDate.replaceFirst("-0", "-").replaceFirst("-", "年")+"月份出貨表");            //yyyy-MM 2010-08
        
        //獲取模板文件中的樣式
        nRow = sheet.getRow(2);
        nCell = nRow.getCell(1);
        CellStyle customNameStyle = nCell.getCellStyle();            //獲取客戶名稱樣式
        
        nRow = sheet.getRow(2);
        nCell = nRow.getCell(2);
        CellStyle contractNoStyle = nCell.getCellStyle();
        
        nRow = sheet.getRow(2);
        nCell = nRow.getCell(3);
        CellStyle productNoStyle = nCell.getCellStyle();
        
        nRow = sheet.getRow(2);
        nCell = nRow.getCell(4);
        CellStyle cnumberStyle = nCell.getCellStyle();
        
        nRow = sheet.getRow(2);
        nCell = nRow.getCell(5);
        CellStyle factoryStyle = nCell.getCellStyle();
        
        nRow = sheet.getRow(2);
        nCell = nRow.getCell(6);
        CellStyle extStyle = nCell.getCellStyle();
        
        nRow = sheet.getRow(2);
        nCell = nRow.getCell(7);
        CellStyle dateStyle = nCell.getCellStyle();
        
        nRow = sheet.getRow(2);
        nCell = nRow.getCell(9);
        CellStyle tradeTermsStyle = nCell.getCellStyle();
        
        for(int i=0;i<oList.size();i++){
            colNo = 1;
            OutProduct op = oList.get(i);                     //獲取每個出貨表對象
            
            nRow = sheet.createRow(rowNo++);                //創(chuàng)建行
            nRow.setHeightInPoints(24);                        //行高
            
            nCell = nRow.createCell(colNo++);                //創(chuàng)建單元格
            nCell.setCellValue(op.getCustomName());
            nCell.setCellStyle(customNameStyle);
            
            nCell = nRow.createCell(colNo++);
            nCell.setCellValue(op.getContractNo());
            nCell.setCellStyle(contractNoStyle);
            
            nCell = nRow.createCell(colNo++);
            nCell.setCellValue(op.getProductNo());
            nCell.setCellStyle(productNoStyle);
            
            nCell = nRow.createCell(colNo++);
            nCell.setCellValue(op.getCnumber());
            nCell.setCellStyle(cnumberStyle);
            
            nCell = nRow.createCell(colNo++);
            nCell.setCellValue(op.getFactoryName());
            nCell.setCellStyle(factoryStyle);
            
            nCell = nRow.createCell(colNo++);
            nCell.setCellValue("附件");

            List<String> extNameList = outProductService.getExtName(op.getContractProductId());
            String _extName = "";
            if(extNameList!=null&&extNameList.size()>0){
                for(String extName : extNameList){
                    _extName += extName + "
";                //換行符
                }
                _extName = _extName.substring(0,_extName.length()-1);        //去掉最后一個字符
            }else{
                _extName = "無";
            }
            nCell.setCellValue(_extName);
            nCell.setCellStyle(extStyle);
            
            nCell = nRow.createCell(colNo++);
            //nCell.setCellValue(UtilFuns.dateTimeFormat(op.getDeliveryPeriod()));        //利用工具類轉(zhuǎn)類型,同時進行格式化
            nCell.setCellValue(op.getDeliveryPeriod());
            nCell.setCellStyle(dateStyle);
            
            nCell = nRow.createCell(colNo++);
            //nCell.setCellValue(UtilFuns.dateTimeFormat(op.getShipTime()));
            nCell.setCellValue(op.getShipTime());
            nCell.setCellStyle(dateStyle);
            
            nCell = nRow.createCell(colNo++);
            nCell.setCellValue(op.getTradeTerms());
            nCell.setCellStyle(tradeTermsStyle);
        }
        
        
        DownloadUtil du = new DownloadUtil();

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();            //生成流對象
        wb.write(byteArrayOutputStream);
        du.download(byteArrayOutputStream, response, "出貨表.xls");        //彈出下載框,用戶就可以直接下載
    }
    

下面是導(dǎo)出下載后的結(jié)果:

String path=request.getSession().getServletContext().getRealPath("/")+"/make/xlsprint";//必須是/的虛擬路徑,不然jdk1.8不會拼接/后面的字符串  ,這紅色的斜杠最好加上,多個斜杠,底層會處理,不要緊
        InputStream is =new FileInputStream(new File(path+"/tOUTPRODUCT.xls"));//這里紅色/也一樣,不加也可以
        HSSFWorkbook wb =new HSSFWorkbook(is);

總結(jié)

以上是生活随笔為你收集整理的poi的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。