使用iText实现将CSDN博客保存为PDF文档

Csdn作为开发者的专业社区,是最流行的技术学习总结和分享交流的平台。但有时候我们也需要将学习总结的技术做线下分享,因此我们可能希望将我们Csdn的博客,保存成线下文档。本文将介绍如何基于iText实现将Csdn的博客保存为PDF文档保存。

iText简介

iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。

获取博客内容

本文介绍基于Android平台的转换方法,其他运行Java的平台,包括Kotlin Multiplatform、JavaWeb等都可以使用该方法。

使用Okhttp3框架访问博客链接,并获取博客内容并将结果转换成InputStream。

    val serverResponse =
        OkHttpReqKit.requestServer("$ASSISTANT_SERVER$ASSISTANT_CONVERT_PATH?url=$url")   // 借助服务器将内容将博客内容格式化

    val result = serverResponse.body?.string()?.let {
        JSON.parse(it)
    }
    val serverUri =
        (result as? JSONObject)?.takeIf { it.getString("state") == "ok" }?.getString("path")
            ?: return null
    val response = OkHttpReqKit.requestServer("$ASSISTANT_SERVER$serverUri")
    val inputStream = response.toString().byteInputStream(charset = Charset.forName("utf-8") // 将博客内容转成inputStream备用

生成PDF文档

将iText功能封装成一个工具类HtmlToPdfKit。

object HtmlToPdfKit {
    fun convertToPdf(
        inputStream: InputStream?,
        waterMark: String?,
        outputStream: OutputStream?
    ) {
        inputStream ?: return
        val defaultFontProvider = DefaultFontProvider(false, false, true, "仿宋")

        val properties = ConverterProperties().also {
            it.setFontProvider(defaultFontProvider)
        }
        val pdfWriter = PdfWriter(outputStream)
        val pdfDocument = PdfDocument(pdfWriter).also {
            // 设置为A4大小
            it.defaultPageSize = PageSize.A4
            waterMark?.let { wm ->
                it.addEventHandler(PdfDocumentEvent.INSERT_PAGE, WaterMarkEventHandler(wm)) // 添加水印
            }
            it.addEventHandler(PdfDocumentEvent.END_PAGE, PageEventHandler())  // 添加页脚
        }
        readInputStream(inputStream)?.use {
            HtmlConverter.convertToPdf(it, pdfDocument, properties)
            pdfWriter.close()
            pdfDocument.close()
        } ?: LogTool.e("转换失败")
    }

    private fun readInputStream(inputStream: InputStream): InputStream? = try {
        var content: String?
        ByteArrayOutputStream().use {
            var len: Int
            val buffer = ByteArray(1024)
            while ((inputStream.read(buffer).also { len = it }) != -1) {
                it.write(buffer, 0, len)
            }
            content = it.toString()
        }
        content?.let {
            val regexSpecial = "&[a-zA-Z]{1,10};"
            val replaceAll: String =
                Pattern.compile(regexSpecial, Pattern.CASE_INSENSITIVE).matcher(it).replaceAll("")
                    .also { res ->
                        LogTool.i("replaced str = $res")
                    }
            getStringStream(replaceAll)
        }
    } catch (e: Exception) {
        LogTool.e("错误信息:${e.message}")
        null
    }

    private fun getStringStream(string: String?): InputStream? = try {
        string?.takeIf { it.trim().isNotEmpty() }?.toByteArray()?.let {
            ByteArrayInputStream(it)
        }
    } catch (ioe: IOException) {
        LogTool.e("错误信息:${ioe.message}")
        null
    }
}

iTextPdfDocument中,可以通过添加EventHandler来处理页眉、页脚、水印等。

class PageEventHandler : IEventHandler {
    override fun handleEvent(event: Event) {
        val documentEvent = event as PdfDocumentEvent
        val document = documentEvent.document
        val page = documentEvent.page
        val pageSize: Rectangle = page.pageSize

        val pdfFont: PdfFont? = try {
            PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false)
        } catch (e: IOException) {
            e.printStackTrace()
            null
        }

        val pdfCanvas = PdfCanvas(page.lastContentStream, page.resources, document)
        val canvas = Canvas(pdfCanvas, pageSize)
        val x: Float = (pageSize.left + pageSize.right) / 2
        val y: Float = pageSize.bottom + 15
        val paragraph: Paragraph =
            Paragraph("第" + document.getPageNumber(page) + "页/共" + document.numberOfPages + "页")
                .setFontSize(10f)
                .setFont(pdfFont)
        canvas.showTextAligned(paragraph, x, y, TextAlignment.CENTER)
        canvas.close()
    }
}
class WaterMarkEventHandler @JvmOverloads constructor(
    // 水印内容
    private val waterMarkContent: String,
    
    //一页中有几列水印    
    private val waterMarkX: Int = 5,

    // 一页中每列有多少水印
    private val waterMarkY: Int = 5
) :
    IEventHandler {
    override fun handleEvent(event: Event) {
        val documentEvent = event as PdfDocumentEvent
        val document = documentEvent.document
        val page = documentEvent.page
        val pageSize: Rectangle = page.pageSize

        val pdfFont: PdfFont? = try {
            PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false)
        } catch (e: IOException) {
            e.printStackTrace()
            null
        }

        val pdfCanvas = PdfCanvas(page.newContentStreamAfter(), page.resources, document)
        val canvas: Canvas = Canvas(pdfCanvas, pageSize).also {
            it.setFontColor(WebColors.getRGBColor("lightgray"))
            it.setFontSize(16f)
            it.setFont(pdfFont)
        }

        val waterMark: Paragraph = Paragraph(waterMarkContent).setOpacity(0.5f)
        for (i in 0 until waterMarkX) {
            for (j in 0 until waterMarkY) {
                canvas.showTextAligned(
                    waterMark,
                    (150 + i * 300f),
                    (160 + j * 150f),
                    document.numberOfPages,
                    TextAlignment.CENTER,
                    VerticalAlignment.BOTTOM,
                    120f
                )
            }
        }
        canvas.close()
    }
}

再将Html内容的inputStream传入工具类,即可将内容转换成PDF保存。

直接使用工具

但如果你不想自己实现该功能,也可以关注公众号”梦想周游世界的猿同学“,或扫码关注。

关注公众号后,如需要将这篇博客Gerrit使用和配置转成PDF保存,只需给公众号发送如下消息:

发送消息后稍作等待,按提示发送”我的文档“,即可获取pdf文档下载链接。

接下来,我们只需点击文档地址链接,即可下载pdf文档。

浏览器提示已阻止不安全的下载时,选择保留。 下载完成后,点击文档打开。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用iText库可以将本地的Word文件转换为PDF。首先,你需要准备好iText库的依赖。然后,你可以使用以下代码来实现转换: ```java import com.itextpdf.text.Document; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.text.Paragraph; import java.io.FileInputStream; import java.io.FileOutputStream; public class WordToPdfConverter { public static void main(String\[\] args) { try { // 读取Word文件 FileInputStream fis = new FileInputStream("path/to/word.docx"); // 创建PDF文件 Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("path/to/output.pdf")); document.open(); // 将Word文件内容写入PDF document.add(new Paragraph("Hello, World!")); // 关闭文件流 document.close(); writer.close(); fis.close(); System.out.println("Word文件转换为PDF成功!"); } catch (Exception e) { e.printStackTrace(); } } } ``` 请注意,上述代码只是一个简单的示例,你需要根据实际情况进行修改。你需要将"path/to/word.docx"替换为你的本地Word文件的路径,将"path/to/output.pdf"替换为你希望生成的PDF文件的路径。你还可以根据需要添加更多的内容到PDF文件中。 希望这个例子能帮到你! #### 引用[.reference_title] - *1* *3* [java使用poi、itextpdf将word、ppt转为pdf文件,并对pdf文件加盖签章](https://blog.csdn.net/m0_67394002/article/details/126032678)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Java实现PDF生成(Word文档Pdf)](https://blog.csdn.net/zxy855/article/details/122495989)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值