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模版里的设置:

表格一:

表格二:

表格三:

以上是我处理动态表格的一些经过,在此分享给大家,希望多多交流,不足之处还请多多指教

在Spring Boot中使用poi-tl库来导出带有合并列的Word表格并下载,您可以按照以下步骤操作: 1. 首先,确保您的Spring Boot项目中已经添加了poi-tl的依赖。您可以在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.6.0</version> </dependency> ``` 2. 创建一个Controller来处理导出请求。例如,创建一个名为WordExportController的类,并添加一个处理导出请求的方法。 ```java import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.data.*; import com.deepoove.poi.util.BytePictureUtils; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.apache.poi.xwpf.usermodel.XWPFTableRow; import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; @Controller public class WordExportController { @GetMapping("/export") public ResponseEntity<InputStreamResource> exportWord() throws IOException { // 创建一个数据模型 List<List<String>> tableData = new ArrayList<>(); tableData.add(createRow("Merged Cells", "Cell 3")); tableData.add(createRow("Cell 4", "Cell 6")); // 使用poi-tl的XWPFTemplate来生成Word文档 XWPFTemplate template = XWPFTemplate.compile("templates/template.docx").render( new DataTable(tableData) .setHeader(createRow("Header 1", "Header 2")) .setCellWidth(2000) // 设置单元格宽度 .setHeaderCellStyle(new CellStyle().setBold(true).setColor("FFFFFF").setBgColor("336699")) .setOddRowCellStyle(new CellStyle().setColor("FFFFFF").setBgColor("99CCFF")) .setEvenRowCellStyle(new CellStyle().setColor("FFFFFF").setBgColor("CCEEFF")) ); // 将生成的Word文档换为字节数组 ByteArrayOutputStream out = new ByteArrayOutputStream(); template.write(out); byte[] documentBytes = out.toByteArray(); // 设置下载响应的头信息 HttpHeaders headers = new HttpHeaders(); headers.setContentDispositionFormData("attachment", "merged_table.docx"); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); // 创建一个包含Word文档字节数组的InputStreamResource InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(documentBytes)); // 返回响应实体 return ResponseEntity.ok() .headers(headers) .body(resource); } private List<String> createRow(String cell1, String cell2) { List<String> row = new ArrayList<>(); row.add(cell1); row.add(cell2); return row; } } ``` 3. 在resources目录下创建一个名为template.docx的Word模板文件。在模板文件中,您可以根据自己的需求设置表格样式和内容。 4. 启动您的Spring Boot应用程序,并访问导出请求的URL(例如:http://localhost:8080/export)。将会自动下载名为merged_table.docx的Word文档,其中包含合并列的表格。 请确保按照您的需求修改代码,并根据模板文件的位置进行相应的调整。 希望对您有所帮助!如果您有任何其他问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值