先将excel转paf
https://blog.csdn.net/qq_42761569/article/details/121699594
Kotlin
package util
import com.aspose.cells.License
import com.aspose.cells.PdfSaveOptions
import com.aspose.cells.Workbook
import com.geolo.desktop.common.utils.LogUtils
import java.io.FileOutputStream
object ExcelUtils {
/**
* excel 转 pdf
*
* @param excelFilePath excel文件路径
* @param convertSheets 需要转换的sheet
*/
fun excel2pdf(excelFilePath: String, convertSheets: IntArray?) {
excel2pdf(excelFilePath, null, convertSheets)
}
/**
* excel 转 pdf
*
* @param excelFilePath excel文件路径
* @param pdfFilePath pdf文件路径
* @param convertSheets 需要转换的sheet
*/
/**
* excel 转 pdf
*
* @param excelFilePath excel文件路径
*/
/**
* excel 转 pdf
*
* @param excelFilePath excel文件路径
* @param pdfFilePath pdf文件路径
*/
@JvmOverloads
fun excel2pdf(
excelFilePath: String,
pdfFilePath: String? = null,
convertSheets: IntArray? = null
) {
var pdfFilePath = pdfFilePath
try {
pdfFilePath = pdfFilePath ?: getPdfFilePath(excelFilePath)
// 验证 License
license
val wb = Workbook(excelFilePath)
val fileOS = FileOutputStream(pdfFilePath)
val pdfSaveOptions = PdfSaveOptions()
pdfSaveOptions.onePagePerSheet = true
if (null != convertSheets) {
printSheetPage(wb, convertSheets)
}
wb.save(fileOS, pdfSaveOptions)
fileOS.flush()
fileOS.close()
LogUtils.d("Excel convert success")
} catch (e: Exception) {
LogUtils.d("Excel convert failed")
e.printStackTrace()
}
}
/**
* 获取 生成的 pdf 文件路径,默认与源文件同一目录
*
* @param excelFilePath excel文件
* @return 生成的 pdf 文件
*/
private fun getPdfFilePath(excelFilePath: String): String {
return excelFilePath.split(".".toRegex()).dropLastWhile { it.isEmpty() }
.toTypedArray()[0] + ".pdf"
}
private val license: Unit
/**
* 获取 license 去除水印
* 若不验证则转化出的pdf文档会有水印产生
*/
get() {
val licenseFilePath = "excel-license.xml"
try {
val `is` = ExcelUtils::class.java.classLoader.getResourceAsStream(licenseFilePath)
val license = License()
license.setLicense(`is`)
} catch (e: Exception) {
LogUtils.d("license verify failed")
e.printStackTrace()
}
}
/**
* 隐藏workbook中不需要的sheet页。
*
* @param sheets 显示页的sheet数组
*/
private fun printSheetPage(wb: Workbook, sheets: IntArray?) {
for (i in 1 until wb.worksheets.count) {
wb.worksheets[i].isVisible = false
}
if (null == sheets || sheets.size == 0) {
wb.worksheets[0].isVisible = true
} else {
for (i in sheets.indices) {
wb.worksheets[i].isVisible = true
}
}
}
}
适用于window平台的desktop应用破的 pff预览view
https://github.com/Patr1ick/fxPDF?tab=readme-ov-file
预览控件
Kotlin
package ui.pdfpreview
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.awt.SwingPanel
import com.geolo.desktop.common.utils.LogUtils
import eu.patrickgeiger.fxpdf.util.PDF
import eu.patrickgeiger.fxpdf.viewer.MinimalViewer
import javafx.application.Platform
import javafx.embed.swing.JFXPanel
import javafx.scene.Scene
import javafx.scene.layout.StackPane
import java.io.File
@Composable
fun PdfPreview(
state: PdfPreviewState,
modifier: Modifier = Modifier,
onCreated: (MinimalViewer) -> Unit = {},
onDispose: (MinimalViewer) -> Unit = {},
) {
var minimalViewer by remember { mutableStateOf<MinimalViewer?>(null) }
val currentOnDispose by rememberUpdatedState(onDispose)
minimalViewer?.let {
DisposableEffect(it) {
onDispose {
it.pdf.closeDocument() //关闭文档
currentOnDispose(it)
}
}
}
SwingPanel(factory = {
JFXPanel().also { jfxP ->
Platform.runLater {
val rootVewView = MinimalViewer.MinimalViewerBuilder()
.setPDF(PDF(File(state.filePath)))
.build()
minimalViewer = rootVewView
val root = StackPane()
root.children.add(minimalViewer)
val scene = Scene(root)
onCreated.invoke(rootVewView)
jfxP.scene = scene
Platform.enterNestedEventLoop("main") //退出后可重新进入
}
}
}, modifier = modifier) {jfxpannel->
}
}
class PdfPreviewState(
val filePath: String
)