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
相关产品推荐
相关产品推荐

