You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中如何用do while循环在iText里设置rowspan

iText PDF表格Rowspan设置失效问题

我通过do while循环从数据库读取20行数据生成PDF表格,尝试为最后几组数据设置rowspan属性,但始终无法成功,最后几组数据出现显示断裂的情况。

原代码

PdfPTable tablel = new PdfPTable(3);
tablel.setWidthPercentage(100);

//Header
PdfPCell cell1 = new PdfPCell(new Phrase("S No"));
PdfPCell cell2 = new PdfPCell(new Phrase("Parameter"));
PdfPCell cell3 = new PdfPCell(new Phrase("Unit"));

tablel.addCell(cell1);
tablel.addCell(cell2);
tablel.addCell(cell3);

//Datas
Cursor c= dbs.query("kiosk_trn_tsoilparameter", new String[]{"soilparam_gid","soilparam_soil_gid","soil_parameter","soil_uom","soil_results"
                }, "soilparam_soil_gid" + "=? COLLATE NOCASE",
                new String[]{id}, null, null, null, null);
                
int i = 1;
if (c.moveToFirst()) {
    do {
        //to get increment values of i
        String group = String.valueOf(i);
        cell1 = new PdfPCell(new Phrase(group));
        tablel.addCell(cell1);
        
        String selectQuery1 = "SELECT  * FROM core_mst_tmaster....";
        Cursor cursor1 = dbs.rawQuery(selectQuery1, null);              
        if(cursor1.moveToNext())
        {
            String machine = cursor1.getString(0);
            cell1 = new PdfPCell(new Phrase(machine));
            tablel.addCell(cell1);
        }
        
        String selectQuery2 = "SELECT  * FROM core_mst_tmaster ....";
        Cursor cursor2 = dbs.rawQuery(selectQuery3, null);              
        if(cursor2.moveToNext())
        {
            String machine = cursor2.getString(0);
            cell2 = new PdfPCell(new Phrase(machine));
            tablel.addCell(cell2);
        }
        String selectQuery3 = "SELECT  * FROM core_mst_tmaster.... ";
        Cursor cursor3 = dbs.rawQuery(selectQuery3, null);              
        if(cursor3.moveToNext())
        {
            String machine = cursor3.getString(0);
            cell3 = new PdfPCell(new Phrase(machine));
            cell3.setRowspan(3);
            tablel.addCell(cell3);
        }
        i++;
        while (c.moveToNext());
    }
document.add(tablel);

尝试过的修正代码

//to get first set of values
if(i==1){
    String machine = cursor3.getString(0);
    cell3 = new PdfPCell(new Phrase(machine));                        
    tablel.addCell(cell3);
}else{
// to get remaining values
    String machine = cursor3.getString(0);
    cell3 = new PdfPCell(new Phrase(machine));
    cell3.setRowspan(3);
    tablel.addCell(cell3);
}

问题分析与解决方案

1. 循环结构错误

原代码的do-while语法完全错误:while (c.moveToNext());被写在了do代码块内部,导致循环只会执行一次,后续数据根本不会被处理。正确的do-while结构应该是:

if (c.moveToFirst()) {
    do {
        // 处理当前行逻辑
        i++;
    } while (c.moveToNext());
}

2. Rowspan使用逻辑错误

在iText中,当给单元格设置rowspan=N时,后续N-1行的对应列不能再添加任何单元格,否则会破坏表格的列数平衡,导致显示断裂。比如你设置某个单元格rowspan=3,意味着这个单元格会占据当前行及接下来2行的位置,所以接下来的2行中,该列不需要再添加单元格。

假设你需要每3行设置一次rowspan=3,逻辑应该是:

  • 第1、4、7...行:添加带rowspan=3的第三列单元格
  • 第2、3、5、6...行:跳过第三列的单元格添加

3. 变量名错误与资源泄漏

  • selectQuery2对应的查询用了selectQuery3变量,属于笔误,会导致SQL错误
  • 所有数据库Cursor使用后未调用close(),会造成资源泄漏

修正后的代码示例

PdfPTable tablel = new PdfPTable(3);
tablel.setWidthPercentage(100);

// 表头
PdfPCell cell1 = new PdfPCell(new Phrase("S No"));
PdfPCell cell2 = new PdfPCell(new Phrase("Parameter"));
PdfPCell cell3 = new PdfPCell(new Phrase("Unit"));
tablel.addCell(cell1);
tablel.addCell(cell2);
tablel.addCell(cell3);

Cursor c = dbs.query("kiosk_trn_tsoilparameter", 
                    new String[]{"soilparam_gid","soilparam_soil_gid","soil_parameter","soil_uom","soil_results"},
                    "soilparam_soil_gid = ? COLLATE NOCASE",
                    new String[]{id}, 
                    null, null, null, null);

int i = 1;
int totalRows = c.getCount();
if (c.moveToFirst()) {
    do {
        // 添加第一列(序号)
        String group = String.valueOf(i);
        cell1 = new PdfPCell(new Phrase(group));
        tablel.addCell(cell1);

        // 添加第二列(Parameter)
        String selectQuery1 = "SELECT * FROM core_mst_tmaster WHERE ..."; // 补充关联当前行的查询条件
        Cursor cursor1 = dbs.rawQuery(selectQuery1, null);              
        if(cursor1.moveToNext()){
            String param = cursor1.getString(0);
            cell1 = new PdfPCell(new Phrase(param));
            tablel.addCell(cell1);
        } else {
            // 无数据时添加空单元格占位
            tablel.addCell(new PdfPCell(new Phrase("")));
        }
        cursor1.close(); // 关闭cursor

        // 处理第三列(Unit)的rowspan逻辑
        int remainingRows = totalRows - i + 1;
        int rowspanValue = Math.min(3, remainingRows); // 最后一组不足3行时,调整rowspan值
        if (i % 3 == 1) { 
            String selectQuery3 = "SELECT * FROM core_mst_tmaster WHERE ..."; // 补充关联当前行的查询条件
            Cursor cursor3 = dbs.rawQuery(selectQuery3, null);              
            if(cursor3.moveToNext()){
                String unit = cursor3.getString(0);
                cell3 = new PdfPCell(new Phrase(unit));
                cell3.setRowspan(rowspanValue);
                tablel.addCell(cell3);
            } else {
                PdfPCell emptyCell = new PdfPCell(new Phrase(""));
                emptyCell.setRowspan(rowspanValue);
                tablel.addCell(emptyCell);
            }
            cursor3.close();
        }
        // 非每3行的第一行,跳过第三列的添加(因为已经被rowspan覆盖)

        i++;
    } while (c.moveToNext());
}
c.close(); // 关闭主cursor
document.add(tablel);

额外提示

  • 确保你的SQL查询逻辑正确,selectQuery1、selectQuery3需要关联当前行的soil_parameter或其他字段,而不是固定查询整个表
  • 最后一组数据不足3行时,要动态调整rowspan值,避免表格结构失衡

内容的提问来源于stack exchange,提问作者Venkat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 21:55:25