java導出pdf報告之四:poi-tl的使用-表格模版

poi的好用之處很大體現在它的表格處理上,接下來我就結合我的實際應用來看看它的使用

首先我們來看看第一個表格,這是一個很普通的表格:

這個表格其實只需要按照poi-tl一般的表格處理進行數據填充就可以了

模板裏使用:{{#flora_table }}

代碼如下:

reportDatas.put("flora_table",new MiniTableRenderData(getFloraTableHead(),getFloraTable(floraList)));

#floraList:參數列表

#添加表頭
private RowRenderData getFloraTableHead() {
    RowRenderData headData = new RowRenderData();
    Style style = new Style(); //設置單元格格式
    style.setFontSize(10);
    style.setFontFamily("宋體");
    headData.setCellDatas(new ArrayList<CellRenderData>(){{
         add(new CellRenderData(new TextRenderData("名稱",style)));
         add(new CellRenderData(new TextRenderData("百分比",style)));
    }});
    TableStyle tableStyle = new TableStyle();
    tableStyle.setBackgroundColor("388E8E"); //設置行格式
    tableStyle.setAlign(STJc.CENTER);
    headData.setRowStyle(tableStyle);
    return headData;
}

#添加表數據
private List<RowRenderData> getFloraTable(List<CheckItem> floraList) {
        List<RowRenderData> rowList = new ArrayList<RowRenderData>();
        for (CheckItem item:floraList) {
            RowRenderData rowRenderData = new RowRenderData();
            List<CellRenderData> cells = new ArrayList<CellRenderData>();
            String cell_1_text = ((BacteriaInfo)ParamMapConstants.getValue("BACTERIA_INFO_MAP",item.getCheckItem())).getCnName() + "(" + item.getCheckItem() + ")";
            Style style = new Style();
            style.setFontSize(10);
            style.setFontFamily("宋體");
            TableStyle tableStyle = new TableStyle();
            tableStyle.setAlign(STJc.CENTER);
            CellRenderData cell_1 = new CellRenderData(new TextRenderData(cell_1_text,style),tableStyle);

            String cell_2_text = item.getCheckValue()+"%";
            TableStyle tableStyle_2 = new TableStyle();
            tableStyle.setAlign(STJc.CENTER);
            CellRenderData cell_2 = new CellRenderData(new TextRenderData(cell_2_text,style),tableStyle_2);
            cells.add(0,cell_1);
            cells.add(1,cell_2);
            rowRenderData.setCellDatas(cells);
            rowList.add(rowRenderData);
        }
        return rowList;
    }

在實現這個表格的時候,生成的word確實沒什麼問題,但使用xdocreport轉成pdf後發現表格的邊框爲深黑色,文字靠下展示,特別是表頭,加上兩列被自動設置爲寬度平均分割,影響到了整個pdf的美觀。最後決定換一種方式去實現,於是先嚐試將表格的邊框調成淺灰色,再次轉的時候,發現pdf的邊框變成了先灰色,基本解決了邊框的問題

對於列寬的問題,我發現只要不是自動生成的整體表格,即在word模版中被固定了列寬和行高的表格,轉的時候列寬和行高是保持原樣的。於是我找到了poi-tl的另一項功能,個性化插件開發,具體使用可以參考其幫助文檔

我的實現如下:


public class IndiTableRenderPolicy extends DynamicTableRenderPolicy {

    int goodsStartRow = 1;

    @Override
    public void render(XWPFTable table, Object data) {
        MiniTableRenderData renderData = (MiniTableRenderData)data;
        List<RowRenderData> goods = renderData.getDatas();
        table.setInsideHBorder(XWPFTable.XWPFBorderType.SINGLE,1,1,"D0CECE"); //設置table的內部橫向邊框
        table.setInsideVBorder(XWPFTable.XWPFBorderType.SINGLE,1,1,"D0CECE");//設置table的內部縱向邊框
        table.setBottomBorder(XWPFTable.XWPFBorderType.SINGLE,1,1,"D0CECE"); //設置table的頂部邊框
        table.setTopBorder(XWPFTable.XWPFBorderType.SINGLE,1,1,"D0CECE");//設置table的頂部邊框
        table.setLeftBorder(XWPFTable.XWPFBorderType.SINGLE,1,1,"D0CECE");//設置table的頂左邊框
        table.setRightBorder(XWPFTable.XWPFBorderType.SINGLE,1,1,"D0CECE");//設置table的右部邊框
        if (null != goods) {
            table.removeRow(goodsStartRow); //刪除表格第二行
            //根據數據加載表格
            for (int i = 0; i < goods.size(); i++) {
                XWPFTableRow insertNewTableRow = table.insertNewTableRow(goodsStartRow);
                for (int j = 0; j < goods.get(i).size(); j++) {
                    XWPFTableCell cell = insertNewTableRow.createCell();                  
                    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);//設置表格文字上下居中,poi-tl中暫沒有實現該功能,只能調用poi的方法進行設置
                    cell.setWidthType(TableWidthType.AUTO); //設置單元格寬度自動適應
                }
                MiniTableRenderPolicy.Helper.renderRow(table, goodsStartRow, goods.get(i)); //調用poi-tl中的方法加載表格
            }
        }
    }
}

插件實現後,需要將插件初始化到poi-tl中,具體方法如下:

Configure.ConfigureBuilder builder = Configure.newBuilder();
builder.customPolicy("flora_table",new IndiTableRenderPolicy());

表格一的實現就已經完成了,接下來我們看看錶格二和表格三所遇到的問題,其中表格一的問題,在二和三中也有,就不再贅述

這裏表格三最主要的一個問題就是評估裏邊圓點的實現,之前說過,我一開始考慮使用圖片實現的,結果poi-tl不支持在動態表格裏插入圖片,我自己實現的又會莫名的插入一個空行。後來就採用了插入特殊符號來實現。

首先我們將特殊符號轉成字符串,首先我們先獲得特殊符號的符號代碼:

打開word,【插入】->【符號】,找到相應的符號,下邊會顯示符號代碼,如下圖:

 

實現方式如下:

int[] code = {0x25CF};
Style style1 = new Style();
style1.setFontSize(11); //設置符號大小
style1.setColor("229A64"); //設置符號顏色
cell_5 = new CellRenderData(new TextRenderData(new String(code, 0, 1),style1),tableStyle_center); //創建單元格數據
         

表格三:

對於第三個表格的主要問題其實在第一個和第二個表格中都已經解決了:一個是圓點的問題(見表格二),一個邊框的問題(見表格一),還有一個就是單元格上下居中的問題(見表格一)。不過還是遇到一個比較詭異的問題,對於表頭裏文字設置爲居中的時候,轉pdf,文字居然不見了。該爲題我沒做過多的糾結,直接設置爲左靠齊,然後左補空格。

最後放一下三個表格最後在word模版裏的設置:

表格一:

表格二:

表格三:

以上是我處理動態表格的一些經過,在此分享給大家,希望多多交流,不足之處還請多多指教

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章