工具类:将Excel转为Pdf

方法一:使用Apache POI 和IText库

步骤1.在build.gradle中导入相关依赖
	compile('org.apache.poi:poi:4.1.0')
    compile('org.apache.poi:poi-ooxml:4.1.0')
    compile('com.itextpdf:itextpdf:5.5.13')
    compile('com.itextpdf:itext-asian:5.2.0')
步骤2.编写相关工具类
package com.zo.utils

import com.itextpdf.text.*
import com.itextpdf.text.pdf.*
import org.apache.poi.hssf.usermodel.HSSFDateUtil
import org.apache.poi.ss.usermodel.Cell
import org.apache.poi.ss.usermodel.CellType
import org.apache.poi.ss.usermodel.DateUtil
import org.apache.poi.xssf.usermodel.XSSFCell
import org.apache.poi.xssf.usermodel.XSSFSheet
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.io.ByteArrayOutputStream
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.text.DecimalFormat


object ExcelToPdfUtil {

    /**
     * 将excel转化成pdf
     * @sourceExcelPath: excel全路径
     * @targetPdfPath: pdf目标全路径
     */
    fun excelToPdf(sourceExcelPath: String, targetPdfPath: String) {
        // 读取excel文件到流中
        val inputStream = FileInputStream(sourceExcelPath)
        val workbook = XSSFWorkbook(inputStream)
        // 获取excel的工作表数量
        val numberOfSheets = workbook.numberOfSheets
        val list = mutableListOf<ByteArray>()
        for (i in 0 until numberOfSheets) {
            // 获取当前索引的工作表
            val sheet = workbook.getSheetAt(i)
            val stream = ByteArrayOutputStream()
            // 设置PDF纸张大小
            val document = Document(PageSize.A4)
            PdfWriter.getInstance(document, stream)
            // 设置页边距
            document.setMargins(0F, 0F, 0F, 10F)
            document.open()
            // 获取excel每列宽度占比
            val widths = getColWidth(sheet)
            // 初始化pdf中每列的宽度
            val pdfPTable = PdfPTable(widths)
            // 设置表格将在页面中占据的宽度百分比
            pdfPTable.widthPercentage = 98F
            val colCount = widths.size
            // 开始遍历excel内容并绘制pdf
            for (r in sheet.firstRowNum until sheet.physicalNumberOfRows) {
                val row = sheet.getRow(r)
                if (row != null && !row.zeroHeight) {
                    var c = row.firstCellNum.toInt()
                    while (c < if (row.lastCellNum > colCount) colCount else row.lastCellNum.toInt()) {
                        if (c >= row.physicalNumberOfCells) {
                            val pdfPCell = PdfPCell(Phrase(""))
                            pdfPCell.border = 0
                            pdfPTable.addCell(pdfPCell)
                            c += 1
                            continue
                        }
                        val excelCell = row.getCell(c)
                        var value = ""
                        if (excelCell != null) {
                            value = getCellValue(excelCell).toString()
                        }

                        val bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED)
                        //创建Font对象,将基础字体对象,字体大小,字体风格
                        val font = Font(bf, 12F, Font.NORMAL)
                        val pCell = PdfPCell(Paragraph(value, font))
                        val hasBorder = hasBorder(excelCell)
                        if (!hasBorder) {
                            pCell.border = 0
                        }

                        if (excelCell == null) {
                            pCell.horizontalAlignment = Element.ALIGN_CENTER
                            pCell.verticalAlignment = Element.ALIGN_CENTER
                        } else {
                            pCell.horizontalAlignment = getHorAlign(excelCell.cellStyle.alignment.code.toInt())
                            pCell.verticalAlignment = getVerAlign(excelCell.cellStyle.verticalAlignment.code.toInt())
                        }

                        pCell.minimumHeight = row.heightInPoints
                        if (isMergedRegion(sheet, r, c)) {
                            val span = getMergedSpan(sheet, r, c)
                            if (span[0] == 1 && span[1] == 1) { //忽略合并过的单元格
                                c += 1
                                continue
                            }
                            pCell.rowspan = span[0]
                            pCell.colspan = span[1]
                            //合并过的列直接跳过
                            c = c + span[1] - 1
                        }
                        pdfPTable.addCell(pCell)
                        c += 1
                    }
                } else {
                    val pCell = PdfPCell(Phrase(""))
                    pCell.border = 0
                    pCell.minimumHeight = 13F
                    pdfPTable.addCell(pCell)
                }
            }
            document.add(pdfPTable)
            document.close()
            val pdfByte = stream.toByteArray()
            list.add(pdfByte)
            stream.close()
        }

        val document: Document
        val copy: PdfCopy
        var reader: PdfReader? = null
        try {
            document = Document(PdfReader(list[0]).getPageSize(1))
            copy = PdfCopy(document, FileOutputStream(targetPdfPath))
            document.open()
            for (i in 0 until list.size) {
                reader = PdfReader(list[i])
                val numberOfPages = reader.numberOfPages
                for (j in 1..numberOfPages) {
                    document.newPage()
                    val page = copy.getImportedPage(reader, j)
                    copy.addPage(page)
                }
            }
        } catch (e: IOException) {
            error("异常")
        }
        document.close()
        copy.close()
        reader!!.close()
    }

    /**
     * 获取excel中每列宽度的占比
     */
    private fun getColWidth(sheet: XSSFSheet): FloatArray {
        val rowNum: Int = getMaxColRowNum(sheet)
        val row = sheet.getRow(rowNum)
        val cellCount = row.physicalNumberOfCells
        val colWidths = arrayOf(cellCount)
        var sum = 0
        for (i in row.firstCellNum until cellCount) {
            val cell = row.getCell(i)
            if (cell != null) {
                colWidths[i] = sheet.getColumnWidth(i)
                sum += sheet.getColumnWidth(i)
            }
        }
        val colWidthPer = floatArrayOf(cellCount.toFloat())
        for (i in row.firstCellNum until cellCount) {
            colWidthPer[i] = colWidths[i].toFloat() / sum * 100
        }
        return colWidthPer
    }

    /**
     * 获取excel中列数最多的行号
     */
    private fun getMaxColRowNum(sheet: XSSFSheet): Int {
        var rowNum = 0
        var maxCol = 0
        for (r in sheet.firstRowNum until sheet.physicalNumberOfRows) {
            val row = sheet.getRow(r)
            if (row != null && maxCol < row.physicalNumberOfCells) {
                maxCol = row.physicalNumberOfCells
                rowNum = r
            }
        }
        return rowNum
    }

    /**
     * 获取单元格值
     */
    private fun getCellValue(cell: Cell): Any? {
        var result: Any? = ""
        try {
            if (cell.cellType === CellType.NUMERIC || cell.cellType === CellType.FORMULA) {
                result = cell.numericCellValue
                result = if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    // POI Excel 日期格式转换
                    DateUtil.getJavaDate(result)
                } else {
                    DecimalFormat("0.0").format(result)
                }
            } else if (cell.cellType === CellType.STRING) {
                result = cell.stringCellValue
            } else if (cell.cellType === CellType.BOOLEAN) {
                result = cell.booleanCellValue
            } else if (cell.cellType === CellType.ERROR) {
                result = cell.errorCellValue
            }
        } catch (e: Exception) {
            return result
        }
        return result
    }

    /**
     * 判断excel单元格是否有边框
     */
    private fun hasBorder(excelCell: XSSFCell): Boolean {
        val top = excelCell.cellStyle.borderTop.code
        val bottom = excelCell.cellStyle.borderBottom.code
        val left = excelCell.cellStyle.borderLeft.code
        val right = excelCell.cellStyle.borderRight.code
        return top + bottom + left + right > 2
    }

    /**
     * 获取excel单元格数据显示格式
     */
    @Throws(Exception::class)
    private fun getNumStyle(dataFormat: String): String {
        if (dataFormat.isEmpty()) {
            throw Exception("")
        }
        return if (dataFormat.indexOf("%") > -1) {
            dataFormat
        } else {
            dataFormat.substring(0, dataFormat.length - 2)
        }
    }

    /**
     * 判断单元格是否是合并单元格
     */
    private fun isMergedRegion(sheet: XSSFSheet, row: Int, column: Int): Boolean {
        val sheetMergeCount = sheet.numMergedRegions
        for (i in 0 until sheetMergeCount) {
            val range = sheet.getMergedRegion(i)
            val firstColumn = range.firstColumn
            val lastColumn = range.lastColumn
            val firstRow = range.firstRow
            val lastRow = range.lastRow
            if (row in firstRow..lastRow) {
                if (column in firstColumn..lastColumn) {
                    return true
                }
            }
        }
        return false
    }

    /**
     * 计算合并单元格合并的跨行跨列数
     */
    private fun getMergedSpan(sheet: XSSFSheet, row: Int, column: Int): IntArray {
        val sheetMergeCount = sheet.numMergedRegions
        val span = intArrayOf(1, 1)
        for (i in 0 until sheetMergeCount) {
            val range = sheet.getMergedRegion(i)
            val firstColumn = range.firstColumn
            val lastColumn = range.lastColumn
            val firstRow = range.firstRow
            val lastRow = range.lastRow
            if (firstColumn == column && firstRow == row) {
                span[0] = lastRow - firstRow + 1
                span[1] = lastColumn - firstColumn + 1
                break
            }
        }
        return span
    }

    /**
     * excel垂直对齐方式映射到pdf对齐方式
     */
    private fun getVerAlign(align: Int): Int {
        return when (align) {
            1 -> Element.ALIGN_MIDDLE
            2 -> Element.ALIGN_BOTTOM
            3 -> Element.ALIGN_TOP
            else -> Element.ALIGN_MIDDLE
        }
    }

    /**
     * excel水平对齐方式映射到pdf水平对齐方式
     */
    private fun getHorAlign(align: Int): Int {
        return when (align) {
            2 -> Element.ALIGN_CENTER
            3 -> Element.ALIGN_RIGHT
            1 -> Element.ALIGN_LEFT
            else -> Element.ALIGN_CENTER
        }
    }

    /**
     * 格式化数字
     */
    private fun numFormat(pattern: String, num: Double): String? {
        val format = DecimalFormat(pattern)
        return format.format(num)
    }
}

该方法可以处理具有多个工作表(sheet)的excel文件,将excel生成一个对应的pdf文件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于 Apache POI 和 iText 库的工具类,内含文本、Word 和 Excel 文件 PDF 的方法: ``` import java.io.*; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.xssf.usermodel.*; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xwpf.usermodel.*; import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; public class ConvertUtils { /** * 将文本文件转为 PDF 文件 * * @param inputFile 输入文件路径 * @param outputFile 输出文件路径 */ public static void textToPDF(String inputFile, String outputFile) { try { // 读取文本文件 FileReader fr = new FileReader(inputFile); BufferedReader br = new BufferedReader(fr); // 创建 PDF 文件 FileOutputStream fos = new FileOutputStream(outputFile); Document pdfDoc = new Document(); PdfWriter.getInstance(pdfDoc, fos); pdfDoc.open(); // 将文本内容写入 PDF 文件 String line; while ((line = br.readLine()) != null) { pdfDoc.add(new Paragraph(line)); } // 关闭文件流 pdfDoc.close(); br.close(); fr.close(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 将 Word 文件转为 PDF 文件 * * @param inputFile 输入文件路径 * @param outputFile 输出文件路径 */ public static void wordToPDF(String inputFile, String outputFile) { try { // 读取 Word 文件并换为 PDF FileInputStream fis = new FileInputStream(inputFile); XWPFDocument document = new XWPFDocument(fis); // 创建 PDF 文件 FileOutputStream fos = new FileOutputStream(outputFile); Document pdfDoc = new Document(); PdfWriter.getInstance(pdfDoc, fos); pdfDoc.open(); // 将 Word 文件内容写入 PDF 文件中 for (XWPFParagraph paragraph : document.getParagraphs()) { pdfDoc.add(new Paragraph(paragraph.getText())); } // 关闭文件流 pdfDoc.close(); fis.close(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 将 Excel 文件转为 PDF 文件 * * @param inputFile 输入文件路径 * @param outputFile 输出文件路径 */ public static void excelToPDF(String inputFile, String outputFile) { try { // 读取 Excel 文件并换为 PDF FileInputStream fis = new FileInputStream(inputFile); Workbook workbook = null; if (inputFile.toLowerCase().endsWith("xlsx")) { // 读取 Excel 2007+ 文件 workbook = new XSSFWorkbook(fis); } else if (inputFile.toLowerCase().endsWith("xls")) { // 读取 Excel 2003- 文件 workbook = new HSSFWorkbook(fis); } // 创建 PDF 文件 FileOutputStream fos = new FileOutputStream(outputFile); Document pdfDoc = new Document(); PdfWriter.getInstance(pdfDoc, fos); pdfDoc.open(); // 将 Excel 文件内容写入 PDF 文件中 for (int i = 0; i < workbook.getNumberOfSheets(); i++) { Sheet sheet = workbook.getSheetAt(i); for (Row row : sheet) { for (Cell cell : row) { pdfDoc.add(new Paragraph(cell.getStringCellValue())); } } } // 关闭文件流 pdfDoc.close(); fis.close(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 上述代码中需要以下依赖: 1. Apache POI 库(版本 3.17 或更高):需要包含 poi.jar、poi-ooxml.jar、poi-ooxml-schemas.jar、xmlbeans.jar、commons-collections4.jar、commons-compress.jar、curvesapi.jar、ooxml-lib目录下的所有 jar 文件。 2. iText 库(版本 5.5.13 或更高):需要包含 itextpdf.jar 和 itext-asian.jar。 你可以在 Apache POI 和 iText 官网上下载这些依赖。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值