小工具知识网

当前位置: 首页 > 行业知识 > android pdf框架-6,文本生成pdf

行业知识

android pdf框架-6,文本生成pdf

2026-11-15 04:53:43 来源:互联网转载

前���介绍如何使用图片生成pdf,这里介绍如何使用文本生成pdf

()

使用mupdf生成

mupdf生成的pdf略大,字体可以自定义.

生成的代码不复杂,也有好几种,以story的方式生成为例

()
fun createPdfFromText(sourcePath: String, destPath: String): Boolean {        val text = EncodingDetect.readFile(sourcePath)        val mediabox = Rect(0f, 0f, 500f, 707f) //A2        val margin = 10f        var writer = DocumentWriter(destPath, "PDF", "")        var snark = "" +                "" +                "#body { font-family: \"Droid Sans\", sans-serif; }" +                "" +                "" +                text +                ""        val story = Story(snark, "", 12f)        var more: Boolean        do {            val filled = Rect()            val where = Rect(                mediabox.x0 + margin,                mediabox.y0 + margin,                mediabox.x1 - margin,                mediabox.y1 - margin            )            val dev: Device = writer.beginPage(mediabox)            more = story.place(where, filled)            story.draw(dev, Matrix.Identity())            writer.endPage()        } while (more)        writer.close()        writer.destroy()        story.destroy()        return true    }

文档的读取,对于中文,可能会涉及到编码的处理.

先定义mediabox,就是纸张大小,这里是a2

然后用html生成story,最后写入就完成了

如果要自定义样式,颜色这些,api要去查如何使用.并不那么方便.

使用系统sdk生成

系统sdk是基于福昕的代码.但生成时可以使用view来设置样式,然后生成页面.样式比较容易控制,毕竟view长什么样是容易修改的.

读取文本是一样的.

val pdfDocument = PdfDocument()        val pageWidth = PDF_PAGE_WIDTH.toInt()        val pageHeight = PDF_PAGE_HEIGHT.toInt()        val contentView =            LayoutInflater.from(context).inflate(R.layout.pdf_content, parent, false) as TextView        contentView.text = content        val measureWidth = View.MeasureSpec.makeMeasureSpec(pageWidth, View.MeasureSpec.EXACTLY)        val measuredHeight = View.MeasureSpec.makeMeasureSpec(pageHeight, View.MeasureSpec.EXACTLY)        contentView.measure(measureWidth, measuredHeight)        contentView.layout(0, 0, pageWidth, pageHeight)

建立文档对象,然后加载布局

val lineCount = contentView.lineCount        var lineHeight = contentView.lineHeight        if (contentView.lineSpacingMultiplier > 0) {            lineHeight = (lineHeight * contentView.lineSpacingMultiplier).toInt()        }        val layout = contentView.layout        var start = 0        var end: Int        var pageH = 0        val paddingTopAndBottom: Int = Utils.dipToPixel(context, 40f)

设置边距40dp,读取行间距与行数.

因为设置了内容后,由textview自己就能计算出这些,然后根据这些信息,计算我们一页的高宽可以分成几页,然后每一页再用一个布局去生成就行了.

while (i = pageHeight - paddingTopAndBottom) {                Log.d(                    "TextView",                    String.format(                        "============page line:%s,lh:%s,ph:%s==========",                        i,                        lineHeight,                        pageHeight                    )                )                createTxtPage(                    context,                    parent,                    pdfDocument,                    pageWidth,                    pageHeight,                    i + 1,                    sb.toString()                )                pageH = 0                sb.setLength(0)            }            i++        }        if (sb.length > 0) {            Log.d("TextView", "last line ===")            createTxtPage(context, parent, pdfDocument, pageWidth, pageHeight, i, sb.toString())        }

这就是计算的过程,最后要再处理剩下的部分.

对于每一页的显示字符数处理完,接着就是对这些生成页面

private fun createTxtPage(        context: Context?,        parent: ViewGroup?,        pdfDocument: PdfDocument,        pageWidth: Int,        pageHeight: Int,        pageNo: Int,        content: String?    ) {        val contentView =            LayoutInflater.from(context).inflate(R.layout.pdf_content, parent, false) as TextView        contentView.text = content        val pageInfo: PdfDocument.PageInfo =            PdfDocument.PageInfo.Builder(pageWidth, pageHeight, pageNo)                .create()        val page: PdfDocument.Page = pdfDocument.startPage(pageInfo)        val pageCanvas: Canvas = page.getCanvas()        val measureWidth = View.MeasureSpec.makeMeasureSpec(pageWidth, View.MeasureSpec.EXACTLY)        val measuredHeight = View.MeasureSpec.makeMeasureSpec(pageHeight, View.MeasureSpec.EXACTLY)        contentView.measure(measureWidth, measuredHeight)        contentView.layout(0, 0, pageWidth, pageHeight)        contentView.draw(pageCanvas)        // finish the page        pdfDocument.finishPage(page)    }

页面同样用之前的布局,这样保持是一致的,否则高宽计算就不对了.这里因为不需要显示,所以我们要调用measure与layout再draw画出来 

保存就简单了

private fun savePdf(path: String?, document: PdfDocument): Boolean {        val outputStream = FileOutputStream(path)        try {            document.writeTo(outputStream)            return true        } catch (e: IOException) {            e.printStackTrace()        } finally {            document.close()        }        return false    }

上一篇:网易服务器满人怎么卡进去?

下一篇:DedeCMS下载指南,轻松获取,简单安装教程