【问题标题】:Itext 5 Table rows splitting to new page and repeatingItext 5表格行拆分到新页面并重复
【发布时间】:2020-05-13 14:11:44
【问题描述】:

我是第一次使用 itext 5 legacy,我是应用程序开发的新手。 我正在生成一个表格,该表格不断将列拆分为新页面上的新行,并且它会重复数据。

第一个表: 第二个带有拆分列和重复数据的表:

第三张表:

第四张表:

第五张表:

表格必须是一长行。 请帮我纠正这个问题,

代码如下:

    private void createPdf() throws FileNotFoundException, DocumentException,IOException {
       // getIntent().setType("application/pdf");
        Toast.makeText(this,"GENERATING PDF ..."+ directory_path,Toast.LENGTH_LONG).show();
        File file = new File(directory_path+filename);
        if (!file.exists())
        {
            file.mkdirs();
        }
        ProductCondition prodCond = new ProductCondition(true,"GREEN","BFobrourinbiurfufbjfnbbu");
        ProductOperations prodOper = new ProductOperations(true,true,true,1000,986,500,"OBNobdfiuvdob");
        Product product = new Product("bkbukb","sfdvsf","sdfsdfs","1sfdssV45",prodCond,prodOper);
        technicians.addProduct(product);
        Document document = new Document(PageSize.A1.rotate());
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(directory_path+filename));
        document.open();
        PdfPTable table = new PdfPTable(15);
        table.setTotalWidth(5000);
        table.setWidthPercentage(100);
        List<String> listData =new ArrayList<>() ;
        listData = GetTechnicianData(technicians);
        Image image1 = GetImage();
        Image image2 = GetImage();
        table.addCell("Bloop");
        table.addCell("han Solo");
        table.addCell("Hamburger");
        table.addCell("NUmber time");
        table.addCell("boogaloo");
        table.addCell("Boo thang");
        table.addCell("Spanish");
        table.addCell("Inquisition");
        table.addCell("Never ");
        table.addCell("Death");
        table.addCell("Test ");
       // table.addCell("Button");
        table.addCell("Lights");
        table.addCell("Sunshine");
        table.addCell("Comment");
        table.addCell("Images");
        table.setHeaderRows(3);
        table.setFooterRows(1);
        table.getDefaultCell().setBackgroundColor(GrayColor.GRAYWHITE);
        PdfPCell cell;
        Toast.makeText(this,"ADDING PRELIMINARY DATA",Toast.LENGTH_LONG).show();
            for (int c = 0; c < 14; c++) {
                cell = new PdfPCell();
                cell.setFixedHeight(50);
                cell.addElement(new Paragraph(listData.get(c)));
                cell.setHorizontalAlignment(Element.ALIGN_CENTER);
                //cell.setBorder(PdfPCell.NO_BORDER);
                table.addCell(cell);
                table.setKeepTogether(true);
            }
        Paragraph p = new Paragraph();
        p.add(new Chunk(image1,0,0,true));
        p.add(new Chunk(image2,0,0,true));
        cell = new PdfPCell();
        cell.addElement(p);
        //cell.setBorder(PdfPCell.NO_BORDER);
        table.addCell(cell);
        //document.add(table);
        Toast.makeText(this,"ADDING IMAGES...",Toast.LENGTH_LONG).show();

          /*  cell = new PdfPCell();
            Paragraph p = new Paragraph();
            p.add(new Chunk(image1,0,0,true));
            p.add(new Chunk(image1,0,0,true));
            cell.addElement(p);
            table.addCell(cell);*/

       // document.add(table);


        PdfContentByte canvas = writer.getDirectContent();
        PdfTemplate tableTemplate = canvas.createTemplate(5000, 2600);
        table.writeSelectedRows(0, -1, 0, 800, tableTemplate);
        PdfTemplate clip;
        for (int j = 0; j <5000; j += 1000) {
            table.setKeepTogether(true);
            document.newPage();
            for (int i = 2600; i > 0; i -= 1300) {

                clip = canvas.createTemplate(2000, 1300);
                clip.addTemplate(tableTemplate, -j, 1750 - i);
                canvas.addTemplate(clip, 50, 312);
                table.setKeepTogether(true);
                //canvas.addImage(image1);
            }
        }
        // byte [] pdf = Files.readAllBytes(file.toPath());
        Uri filepdf = Uri.fromFile(new File(directory_path+filename));
        UploadTask uploadTask = storageReference.child(technicians.getEmailAddress()).child("PDFUpdate").putFile(filepdf);
        Toast.makeText(this,"PDF Generated Successfully",Toast.LENGTH_LONG).show();
        document.close();

       /* PackageManager packageManager = context.getPackageManager();
        Intent testIntent = new Intent(Intent.ACTION_VIEW);
        testIntent.setType("application/pdf");
        List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
        if (list.size() > 0) {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            Uri uri = Uri.fromFile(file);
            intent.setDataAndType(uri, "application/pdf");
            context.startActivity(intent);
        } else {
            Toast.makeText(context, "Download a PDF Viewer to see the generated PDF", Toast.LENGTH_SHORT).show();
        }
*/
    }
    private void createPdfWrapper() throws FileNotFoundException, DocumentException ,IOException{

        int hasWriteStoragePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (hasWriteStoragePermission != PackageManager.PERMISSION_GRANTED) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    showMessageOKCancel("You need to allow access to Storage",
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                        ActivityCompat.requestPermissions(CentralHome.this, new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE},
                                                REQUEST_CODE_ASK_PERMISSIONS);
                                    }
                                }
                            });
                    return;
                }
                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        REQUEST_CODE_ASK_PERMISSIONS);
                return;
            }

        } else {
            createPdf();
        }
    }

    private Image GetImage() throws BadElementException,IOException{


            Drawable d = getResources().getDrawable(R.drawable.logo);
            BitmapDrawable bitDw = ((BitmapDrawable) d);
            Bitmap bmp = bitDw.getBitmap();
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
            Image image = Image.getInstance(stream.toByteArray());
            image.scalePercent(10);
            return image;
            // document.add(image);

    }

}

【问题讨论】:

  • 我不明白你的预期结果是什么。例如,创建一个包含 3 个标题行和 1 个页脚行的 15 列表,仅页眉和页脚就需要 15*(3+1) = 60 个单元格。但是,您只添加了 31 个单元格,因此您应该预料到问题...
  • 嘿,感谢您对@mkl 的评论,我对 itext 和生成 pdf 完全陌生。它应该每行只有 15 个单元格,但它们会复制并添加到下一页的下一行。查看表1和表2,表1中的一些单元格被复制到表2中

标签: java android itext pdf-generation


【解决方案1】:

createPdf 中,您有一个循环将模板的各个部分与整个表格一起添加到单独的页面中:

for (int j = 0; j <5000; j += 1000) {
    table.setKeepTogether(true);
    document.newPage();
    for (int i = 2600; i > 0; i -= 1300) {
        clip = canvas.createTemplate(2000, 1300);
        clip.addTemplate(tableTemplate, -j, 1750 - i);
        canvas.addTemplate(clip, 50, 312);
        table.setKeepTogether(true);
        //canvas.addImage(image1);
    }
}

每个部分的宽度为 2000 个单位 (canvas.createTemplate(2000, 1300)),但在进入下一个部分时,您只能向右移动 1000 个单位 (j += 1000)。因此,每个新部分(除了第一个部分)都会重复上一部分的最后三列(后半部分)。

您可以通过在每个部分之后向右移动 2000 个单位来防止这些重复,即通过替换

for (int j = 0; j <5000; j += 1000)

通过

for (int j = 0; j <5000; j += 2000)

顺便说一句,您的代码中还有许多其他奇怪之处,例如

table.setHeaderRows(3);
table.setFooterRows(1);

(在这里您声明如果表格直接添加到Document 并拆分为多个页面,您将自动重复三个标题行和一个页脚行;因为您没有将表格添加到Document但是手动到模板,没有使用该功能,这是幸运的,因为您只创建了足够的单元格来填充两行,甚至不足以填充声明的标题行)

以及多次调用

table.setKeepTogether(true)

已经呈现表格之后

table.writeSelectedRows(0, -1, 0, 800, tableTemplate)

渲染表格后,设置控制渲染过程的属性为时已晚...


在评论中,您说您只想拥有一个普通的 15 列表,而不是列分布在多个页面上的表。在那种情况下,你为什么不干脆做

Document document = new Document(PageSize.A1.rotate());
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(directory_path+filename));
document.open();
PdfPTable table = new PdfPTable(15);
table.setWidthPercentage(100);

... create cells and add them to the table ...

document.add(table);
document.close();

PdfContentBytePdfTemplatewriteSelectedRows 的所有用法对于您的用例来说是完全没有必要的。

【讨论】:

  • 非常感谢@mkl,单元格停止复制到下一行。无论如何我可以将所有单元格放在一排吗?并且表在上一行之后立即转到下一行(就像任何普通的数据表一样)而不是下一页?我将document.newPage() 放在外循环中,因为在内循环中,单元格是在彼此之上生成的。
  • “无论如何我可以将所有单元格放在一行上吗?” - 你的意思是,你想要一张有 30 列和 2 行的表格,而不是一张有 15 列和 2 行的表格列和 1 行?只需将table 实例化为new PdfPTable(30) 而不是new PdfPTable(15)“并且还能够在上一行之后立即转到下一行而不是下一页?” - 你是什么意思?表格在PdfTemplate tableTemplate 中被绘制成一个片段,然后您自己的代码 将这个连接的表格分割成片段并将它们分布在多个页面上。如果你不想那样,你为什么要这样做?
  • 我需要一行 15 列。以前它看起来像 30,因为单元格被复制了。但是从我现在得到的输出中,我得到了 3 行中的 5 列。所以我想创建一个动态表,每行有 x 行,每行 15 列,并且它只能在到达页面边界时跳到下一页。我使用了其中一个 itext 示例中的代码并尝试将其调整为我的数据,所以我并没有真正理解其中的一些功能。
  • 如果我理解正确的话,你举了一个完全不恰当的例子。请参阅我的答案的编辑以获取另一种更简单的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-30
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多