在 itextpdf 中创建 pdf 并向其添加图像时,应用程序会暂停一段时间:itext7

App halts for a while when creating pdf and adding image to it in itextpdf: itext7

我正在创建一个应用程序来制作 pdf 并使用存储访问框架向其中写入文本和位图图像。

位图图像是从使用放置在 framelayout 中的 MPAndroidChart 生成的图表中捕获的。仅添加文本时,过程很快。但是当我添加位图图像时,activity 屏幕变黑并在 ~10 秒内没有响应。

在pdf中,我在起始页添加了图片。尽管有足够的 space,图表出现在下一页。

如何在没有分页符的情况下向页面添加图表以消除无响应的屏幕?

var newpdfhandle = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
    resultData: ActivityResult ->
    val uri = resultData.data?.data
    if (resultData.resultCode == Activity.RESULT_OK){
        if (uri != null){
            var bitmap = getBitmapFromView(fragFrame)     // fragFrame = framelayout containing chart
            if (bitmap != null) {                    
                CreateNewPdf.newPdf(this, uri, framelist, bitmap)                    
            }
        }
    }
}

private fun getBitmapFromView(view: View): Bitmap{
    var bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
    var canvas = Canvas(bitmap)
    view.draw(canvas)
    return bitmap
}

Class创建pdf如下:

class CreateNewPdf {

    companion object {    

    val thick_ls = LineSeparator(SolidLine(2f))
    val thin_ls = LineSeparator(SolidLine(1f))
    val tempcolor = DeviceRgb(255, 192, 192)
    val humidcolor = DeviceRgb(0, 172, 192)

    fun newPdf(context: Context, uri: Uri, dataframe: MutableList<DataFrame>, bitmap: Bitmap) {

        val mintemp = dataframe.minBy { it.temperature }?.temperature
        val maxtemp = dataframe.maxBy { it.temperature }?.temperature
        val avgtemp = (dataframe.map { it.temperature }.average() * 10f).toInt().toFloat() / 10f
        val minhumid = dataframe.minBy { it.humidity }?.humidity
        val maxhumid = dataframe.maxBy { it.humidity }?.humidity
        val avghumid = (dataframe.map { it.humidity }.average() * 10f).toInt().toFloat() / 10f

        val filename = queryName(context.contentResolver, uri)

        try {

            var writeStream: OutputStream? = context.contentResolver.openOutputStream(uri, "w")
            val pdf = PdfDocument(PdfWriter(writeStream))
            val document = Document(pdf, PageSize.A4, false)

            val reportTitle = Paragraph("DATA LOGGER REPORT").setFontSize(20f)
                .setTextAlignment(TextAlignment.CENTER)
            document.add(reportTitle)
            document.add(thick_ls)

            var header = Paragraph("1. Summary")
            document.add(header)

            val summary_font = 12f
            val data_font = 8f
            val page_font = 6f

            val table = Table(4, false)
            table.setHorizontalAlignment(HorizontalAlignment.CENTER)

            var cell11: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.LIGHT_GRAY)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph("List").setFontSize(summary_font))
            var cell12: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.LIGHT_GRAY)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph("Maximum").setFontSize(summary_font))
            var cell13: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.LIGHT_GRAY)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph("Minimum").setFontSize(summary_font))
            var cell14: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.LIGHT_GRAY)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph("Average").setFontSize(summary_font))

            val cell21: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.WHITE)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph("Temperature °C").setFontSize(summary_font))
            val cell22: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.WHITE)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph(maxtemp.toString()).setFontSize(summary_font))
            val cell23: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.WHITE)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph(mintemp.toString()).setFontSize(summary_font))
            val cell24: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.WHITE)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph(avgtemp.toString()).setFontSize(summary_font))

            val cell31: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.WHITE)
                .setTextAlignment(TextAlignment.CENTER).add(Paragraph("Humidity %"))
            val cell32: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.WHITE)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph(maxhumid.toString()).setFontSize(summary_font))
            val cell33: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.WHITE)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph(minhumid.toString()).setFontSize(summary_font))
            val cell34: Cell = Cell(1, 1).setBackgroundColor(ColorConstants.WHITE)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph(avghumid.toString()).setFontSize(summary_font))

            table.addCell(cell11)
            table.addCell(cell12)
            table.addCell(cell13)
            table.addCell(cell14)
            table.addCell(cell21)
            table.addCell(cell22)
            table.addCell(cell23)
            table.addCell(cell24)
            table.addCell(cell31)
            table.addCell(cell32)
            table.addCell(cell33)
            table.addCell(cell34)
            document.add(table)

            /*************** BITMAP INSERTION STARTS HERE ***************/

            header = Paragraph("2. Real time chart data").setFontSize(12f)
            document.add(header)

            var stream: ByteArrayOutputStream = ByteArrayOutputStream()
            bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream)
            var img: Image = Image(ImageDataFactory.create(stream.toByteArray()))
            document.add(img)
            
            /*************** BITMAP INSERTION ENDS HERE***************/

            header = Paragraph("3. Log Details").setFontSize(12f)
            document.add(header)
            var dTable = Table(4, false)
            var celld1 = Cell()
            var celld2 = Cell()
            var celld3 = Cell()
            var celld4 = Cell()
            var row = 0
            cell11 = Cell(1, 1).setBackgroundColor(ColorConstants.LIGHT_GRAY)
                .setTextAlignment(TextAlignment.CENTER).add(Paragraph("List").setFontSize(data_font))
            cell12 = Cell(1, 1).setBackgroundColor(ColorConstants.LIGHT_GRAY)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph("Date Time").setFontSize(data_font))
            cell13 = Cell(1, 1).setBackgroundColor(ColorConstants.LIGHT_GRAY)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph("Temperature").setFontSize(data_font))
            cell14 = Cell(1, 1).setBackgroundColor(ColorConstants.LIGHT_GRAY)
                .setTextAlignment(TextAlignment.CENTER)
                .add(Paragraph("Humidity").setFontSize(data_font))
            dTable.addCell(cell11)
            dTable.addCell(cell12)
            dTable.addCell(cell13)
            dTable.addCell(cell14)
            dataframe.forEach {
                row++
                celld1 = Cell(row, 1).setBackgroundColor(ColorConstants.WHITE).setTextAlignment(TextAlignment.CENTER).
                            add(Paragraph(it.count.toString()).setFontSize(data_font)).setWidth(30f)
                celld2 = Cell(row, 1).setBackgroundColor(ColorConstants.WHITE).setTextAlignment(TextAlignment.CENTER).
                            add(Paragraph(it.datetime).
                            setFontSize(data_font)).setWidth(85f)
                celld3 = Cell(row, 1).setBackgroundColor(tempcolor).setTextAlignment(TextAlignment.CENTER).
                            add(Paragraph("${it.temperature.toString()} °C")
                                .setFontSize(data_font)).setWidth(60f)
                celld4 = Cell(row, 1).setBackgroundColor(humidcolor).setTextAlignment(TextAlignment.CENTER).
                            add(Paragraph("${it.humidity.toString()} %")
                                .setFontSize(data_font)).setWidth(60f)

                dTable.addCell(celld1)
                dTable.addCell(celld2)
                dTable.addCell(celld3)
                dTable.addCell(celld4)
            }
            document.add(dTable)

            val n: Int = pdf.numberOfPages
            for (i in 1..n) {
                document.showTextAligned(
                    Paragraph(String.format("Page $i of $n")).setFontSize(page_font),
                    559f, 836f, i,
                    TextAlignment.RIGHT,
                    VerticalAlignment.TOP,
                    0f
                )
            }
            document.flush()

            document.close()
        } catch (e: Exception){
            Toast.makeText(context, "Error when $filename.pdf", Toast.LENGTH_SHORT).show()
        }
    }
}
}

我实现了Runnable接口,并在其中调用了pdf创建函数。我的实现如下:

var newpdfhandle = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
    resultData: ActivityResult ->
    val uri = resultData.data?.data
    if (resultData.resultCode == Activity.RESULT_OK){
        if (uri != null){
            var bitmap = getBitmapFromView(fragFrame)     // fragFrame = framelayout containing chart
            if (bitmap != null) {                    
                
                val myRunnable = Runnable {
                    Handler(Looper.getMainLooper()).post {
                        pdfProgressbar.visibility = View.VISIBLE
                    }
                    CreateNewPdf.newPdf(this, uri, framelist, bitmap)
                    Handler(Looper.getMainLooper()).post {
                        pdfProgressbar.visibility = View.GONE
                    }
                }
                val thread = Thread(myRunnable).start()

            }
        }
    }
}