当前位置: 首页 > news >正文

kmp desktop实现excel预览

先将excel转paf

https://blog.csdn.net/qq_42761569/article/details/121699594

package utilimport com.aspose.cells.License
import com.aspose.cells.PdfSaveOptions
import com.aspose.cells.Workbook
import com.geolo.desktop.common.utils.LogUtils
import java.io.FileOutputStreamobject 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文件路径*/@JvmOverloadsfun excel2pdf(excelFilePath: String,pdfFilePath: String? = null,convertSheets: IntArray? = null) {var pdfFilePath = pdfFilePathtry {pdfFilePath = pdfFilePath ?: getPdfFilePath(excelFilePath)// 验证 Licenselicenseval wb = Workbook(excelFilePath)val fileOS = FileOutputStream(pdfFilePath)val pdfSaveOptions = PdfSaveOptions()pdfSaveOptions.onePagePerSheet = trueif (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

预览控件

package ui.pdfpreviewimport 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 = rootVewViewval root = StackPane()root.children.add(minimalViewer)val scene = Scene(root)onCreated.invoke(rootVewView)jfxP.scene = scenePlatform.enterNestedEventLoop("main") //退出后可重新进入}}}, modifier = modifier) {jfxpannel->}}class PdfPreviewState(val filePath: String
)

http://www.lryc.cn/news/473950.html

相关文章:

  • OB_GINS_day3
  • 【Python3】【力扣题】405. 数字转换为十六进制数
  • 记录一次企业外部通过ssh 连接数据库的事DBeaver
  • 中聚企服:中聚AI女娲大模型,企业难题迎刃而解!
  • 对镜像精简
  • 老电脑不能装纯净版windows
  • 在Python中实现一个简单的社交媒体应用
  • pytest高版本兼容test_data[“log“] = _handle_ansi(“\n“.join(logs))错误
  • Redis技术入门与实践指南
  • 如何一键完成20个Oracle实例运维脚本部署
  • 【C++刷题】力扣-#598-区间加法 II
  • 优雅的LUA数据记录方法-serpent序列化+LUA Table
  • 初始JavaEE篇——多线程(4):wait、notify,饿汉模式,懒汉模式,指令重排序
  • Apache Solr 身份认证绕过导致任意文件读取漏洞复现(CVE-2024-45216)
  • C#整合Ollama实现本地LLMs调用
  • C++基于opencv的视频质量检测--图像抖动检测
  • Cuda By Example - 11 (Texture Memory 2-D)
  • Go匿名结构体使用场景
  • Vue 发布十年了!你知道我这十年是怎么过的吗?
  • Unity 6 来袭
  • SpringMVC课时1
  • 【小白学机器学习30】样本统计的核心参数:均值/期望,方差,标准差,标准值。
  • flink1.17.2安装和使用
  • C向C++入门-- C语言填坑
  • 扫雷游戏(C语言详解)
  • 信刻全自动光盘摆渡系统
  • 计算机网络的数据链路层
  • 从0开始搭建一个生产级SpringBoot2.0.X项目(三)SpringBoot接口统一返回和全局异常处理
  • Mybatis-plus-扩展功能
  • 【AI辅助】AWS Toolkit+AmazonQ