当前位置:   article > 正文

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

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

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

使用mupdf生成

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

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

  1. fun createPdfFromText(sourcePath: String, destPath: String): Boolean {
  2. val text = EncodingDetect.readFile(sourcePath)
  3. val mediabox = Rect(0f, 0f, 500f, 707f) //A2
  4. val margin = 10f
  5. var writer = DocumentWriter(destPath, "PDF", "")
  6. var snark = "<!DOCTYPE html>" +
  7. "<style>" +
  8. "#body { font-family: \"Droid Sans\", sans-serif; }" +
  9. "</style>" +
  10. "<body>" +
  11. text +
  12. "</body></html>"
  13. val story = Story(snark, "", 12f)
  14. var more: Boolean
  15. do {
  16. val filled = Rect()
  17. val where = Rect(
  18. mediabox.x0 + margin,
  19. mediabox.y0 + margin,
  20. mediabox.x1 - margin,
  21. mediabox.y1 - margin
  22. )
  23. val dev: Device = writer.beginPage(mediabox)
  24. more = story.place(where, filled)
  25. story.draw(dev, Matrix.Identity())
  26. writer.endPage()
  27. } while (more)
  28. writer.close()
  29. writer.destroy()
  30. story.destroy()
  31. return true
  32. }

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

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

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

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

使用系统sdk生成

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

读取文本是一样的.

  1. val pdfDocument = PdfDocument()
  2. val pageWidth = PDF_PAGE_WIDTH.toInt()
  3. val pageHeight = PDF_PAGE_HEIGHT.toInt()
  4. val contentView =
  5. LayoutInflater.from(context).inflate(R.layout.pdf_content, parent, false) as TextView
  6. contentView.text = content
  7. val measureWidth = View.MeasureSpec.makeMeasureSpec(pageWidth, View.MeasureSpec.EXACTLY)
  8. val measuredHeight = View.MeasureSpec.makeMeasureSpec(pageHeight, View.MeasureSpec.EXACTLY)
  9. contentView.measure(measureWidth, measuredHeight)
  10. contentView.layout(0, 0, pageWidth, pageHeight)

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

  1. val lineCount = contentView.lineCount
  2. var lineHeight = contentView.lineHeight
  3. if (contentView.lineSpacingMultiplier > 0) {
  4. lineHeight = (lineHeight * contentView.lineSpacingMultiplier).toInt()
  5. }
  6. val layout = contentView.layout
  7. var start = 0
  8. var end: Int
  9. var pageH = 0
  10. val paddingTopAndBottom: Int = Utils.dipToPixel(context, 40f)

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

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

  1. while (i < lineCount) {
  2. end = layout.getLineEnd(i)
  3. val line = content.substring(start, end) //指定行的内容
  4. start = end
  5. sb.append(line)
  6. pageH += lineHeight
  7. if (pageH >= pageHeight - paddingTopAndBottom) {
  8. Log.d(
  9. "TextView",
  10. String.format(
  11. "============page line:%s,lh:%s,ph:%s==========",
  12. i,
  13. lineHeight,
  14. pageHeight
  15. )
  16. )
  17. createTxtPage(
  18. context,
  19. parent,
  20. pdfDocument,
  21. pageWidth,
  22. pageHeight,
  23. i + 1,
  24. sb.toString()
  25. )
  26. pageH = 0
  27. sb.setLength(0)
  28. }
  29. i++
  30. }
  31. if (sb.length > 0) {
  32. Log.d("TextView", "last line ===")
  33. createTxtPage(context, parent, pdfDocument, pageWidth, pageHeight, i, sb.toString())
  34. }

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

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

  1. private fun createTxtPage(
  2. context: Context?,
  3. parent: ViewGroup?,
  4. pdfDocument: PdfDocument,
  5. pageWidth: Int,
  6. pageHeight: Int,
  7. pageNo: Int,
  8. content: String?
  9. ) {
  10. val contentView =
  11. LayoutInflater.from(context).inflate(R.layout.pdf_content, parent, false) as TextView
  12. contentView.text = content
  13. val pageInfo: PdfDocument.PageInfo =
  14. PdfDocument.PageInfo.Builder(pageWidth, pageHeight, pageNo)
  15. .create()
  16. val page: PdfDocument.Page = pdfDocument.startPage(pageInfo)
  17. val pageCanvas: Canvas = page.getCanvas()
  18. val measureWidth = View.MeasureSpec.makeMeasureSpec(pageWidth, View.MeasureSpec.EXACTLY)
  19. val measuredHeight = View.MeasureSpec.makeMeasureSpec(pageHeight, View.MeasureSpec.EXACTLY)
  20. contentView.measure(measureWidth, measuredHeight)
  21. contentView.layout(0, 0, pageWidth, pageHeight)
  22. contentView.draw(pageCanvas)
  23. // finish the page
  24. pdfDocument.finishPage(page)
  25. }

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

保存就简单了

  1. private fun savePdf(path: String?, document: PdfDocument): Boolean {
  2. val outputStream = FileOutputStream(path)
  3. try {
  4. document.writeTo(outputStream)
  5. return true
  6. } catch (e: IOException) {
  7. e.printStackTrace()
  8. } finally {
  9. document.close()
  10. }
  11. return false
  12. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/214488
推荐阅读
相关标签
  

闽ICP备14008679号