kmp desktop实现excel预览

GitHub Store:基于KMP的跨平台开源软件安装客户端 GitHub Releases 作为事实上的开源软件分发层,长期面临元数据缺失、平台适配混乱、安装不可信等基础性问题。其本质是缺乏统一的结构化描述与可复现的交付机制。Kotlin Multiplatform(KMP)凭借共享业务逻辑与原生UI渲染能力,为解决跨平台一致性提供了工程级保障;而 Compose Multiplatform 则进一步实现桌面端像素级一致的交互体验。这类技术组合不仅支撑了安全、原子、可逆的安装流程,更让开发者能聚焦于 Release 数据治理、校验逻辑与系统集成等核心价值环节。本文以 阅读详情

先将excel转paf

https://blog.youkuaiyun.com/qq_42761569/article/details/121699594

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

预览控件

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
)

AionUi:基于.NET 6的跨平台AI办公助手实战指南 AI办公助手正从‘聊天界面’迈向‘意图驱动的工作流引擎’,其核心在于本地化、低延迟与跨平台确定性响应。C# 10与.NET 6凭借单文件发布、内存安全和原生GUI能力,成为构建高性能桌面AI应用的新选择——尤其在PDF解析、Excel联动、离线知识库等办公高频场景中,显著优于Python或Electron方案。AionUi作为典型代表,以MAUI实现深度跨平台适配,用ONNX轻量模型支撑本地意图识别,并通过插件化架构打通文档-数据-邮件闭环。它不依赖云端API,不强制安装运行时,真正实现开箱即用的‘安静生产 阅读详情

相关推荐

Windows纯CPU部署Qwen3-TTS实战:绕过Ollama的离线语音合成方案

语音合成(TTS)是人机交互的基础能力,其核心原理在于将文本序列经编码器、声学模型和声码器三级转换为波形音频;技术价值体现在低延迟、高兼容与强离线性,尤其适用于政企内网、边缘终端等无GPU受限环境。典型应用场景包括国产办公软件语音播报、离线政务终端语音反馈、老旧笔记本嵌入式TTS服务等。本文聚焦Windows平台纯CPU推理落地,直面Ollama不支持Qwen3-TTS架构、PyTorch线程调度失稳、ONNX Runtime默认单线程等关键瓶颈,提供从pyenv-win环境隔离、AVX2加速的onnxru

471

用 Kotlin 多平台开发构建跨平台应用程序:深入探索 KMP 模板工程

KMP 模板工程为开发人员提供了快速入门 KMP 开发的便捷途径。它包含了构建跨平台应用程序所需的基本配置和示例代码,让开发人员可以立即开始开发。KMP 模板工程是一个强大的工具,可用于构建高性能、可维护的跨平台应用程序。Kotlin 多平台开发 (KMP) 是一种强大的工具,可用于构建跨平台移动、桌面和 Web 应用程序。它包含了构建跨平台应用程序所需的基本配置和示例代码,让开发人员可以立即开始开发。KMP模板仍然包含了一些创建好的模板项目,项目展示了一个图片浏览业务。

虎哥LoveDroid 2509

为 Compose MultiPlatform 添加 C/C++ 支持(3):实战 Desktop、Android、iOS 调用同一个 C/C++ 代码

通过上面两个小节的讲解,相信读者也看出问题来了,这时候如果我再说调用 C 的运算速度实际上比直接使用 kotlin 还慢读者应该也恍然大悟知道什么原因了吧。其实并不是 C 本身慢,而在于我为了在调用 C 的同时复用 C 代码,做了大量的数据转换工作,而每次数据转换的代价都是极其昂贵的,这就导致运算时间反而相比于直接使用 kt 计算还要慢了。这也是我说的使用这个项目举例是不恰当的原因,因为这就相当于为了这碗醋还特意去大张旗鼓的包了顿饺子一样。

sinat_17133389的博客 2775

【KMP】桌面端打包指南

KMP这玩意一副管生不管养的样子,要不是我知道是JB和谷歌搞出来的我还以为小米做的呢。早期文档就寥寥几段没什么内容的吹嘘,现在终于有打包指南了。顺着指南摸索了一会儿终于知道怎么打包了。

天枢破军的博客 739

KotlinConf 2024:深入了解Kotlin Multiplatform (KMP)

在近期的Google I/O大会上,我们推荐了Kotlin Multiplatform (KMP)用于跨移动、网页、服务器和桌面平台共享业务逻辑,并在Google Workspace中采用了KMP。紧接着,KotlinConf 2024成为与Kotlin社区分享亮点并交流的重要时刻。

虎哥LoveDroid 3521

Flutter vs Compose:选择哪个?Kotlin在Windows上进行桌面开发Android

Flutter是由Google开发的开源UI工具包,可用于构建高性能、美观的跨平台移动应用程序。使用Flutter,开发人员可以使用单一代码库构建iOS和Android应用,而无需为每个平台单独编写代码。Flutter使用Dart编程语言,提供丰富的UI组件和强大的渲染引擎,可以实现快速的开发周期和流畅的用户体验。Compose是由Google推出的声明性UI工具包,专为构建现代Android应用程序而设计。Compose使用Kotlin编程语言,并利用了Kotlin的语言功能和Android平台的特性。

CodeSpark的博客 864

Compose-jb图片加载库load-the-image,适用于KMM Compose desktop桌面端(Windows,Linux,MacOs)

Android平台上有很多优秀的图片加载框架,比如Glide,Picasso,Fresco而Compose-jetpack上的图片加载框架有Coil但Compose-jb上却暂时没有图片加载框架,正好我有用Compose-jb写一些小工具,有图片加载的需求,于是就仿照Android平台的图片加载库写了一个具有简单功能的图片加载库项目已开源,地址: load-the-image (github.com) 欢迎star功能1.简单的支持多个桌面平台的图片加载(部分格式异步加载)2.支持多种格式:网络链接,本地文

lt的博客 2506

基于鼠标交互的卡通人物设计与绘制,可以对人物五官位置进行拖拽移动调整

根据OpenGL提供的直线,多边形绘制算法(橡皮筋效果),实现基于鼠标交互的卡通人物设计与绘制。使用颜色填充与反走样技术对卡通人物外貌以及衣着进行绘制。实现对卡通人物轮廓的交互控制,点击鼠标左键可以对人物五官位置进行拖拽移动调整。按“↑”按键能够实现卡通人物绕坐标原点(或指定点)进行旋转

基于Kotlin Multiplatform实现静态文件服务器(二)

是Google 为Android开发推出的一种新型UI构建工具,它基于Kotlin语言,采用声明性的语法,使得UI构建更加简单、直观。与传统的XML布局不同,Jetpack Compose使用代码来描述UI,开发者可以直接在代码中设置UI元素的属性,而无需使用XML进行配置。它也可以被用来基于KMP实现跨平台的UI实现,以达到各平台UI一致。

Luckyion的专栏 1435

fxPDF:这是JavaFX的PDF-Viewer库

eu.patrickgeiger.fxpdf.fxPDF 这是JavaFX的PDF查看器库。 文献资料 您可以在找到文档。 执照 该库当前已获得欧盟公共许可证v1.2( )的许可。 图书馆 您可以找到所有使用的库。

zynq+LWIP 裸机双网口实现(MIO+EMIO)+程序下载

芯片型号: ZYNQ: XC7Z010clg400开发软件:Vivado2022 + Xilinx Vitis 2022网卡芯片:RTL8211FDI(需要根据网口芯片型号修改对应的硬件配置代码。

thinking in 小宇宙 3410

Kotlin Compose Multiplatform下全局通知组件构建

在前文Kotlin Compose Multiplatform下全局通知组件构建,我们介绍了在应用软件内的通知方式,这里我们处理应用软件外系统层级的通知的。在安卓端我们正常使用进行消息的通知处理。而在桌面端,由于常用的使用习惯,我们使用系统托盘闪烁的方式进行消息通知,当然这里小伙伴们也可以选择正常的通知方式,如果这样可以参考使用进行处理。

AsterCass的博客 1068

储能EMS工作原理深度剖析:功率分配与充放电策略的底层逻辑

储能EMS的功率分配与充放电策略,是其智能化的集中体现。功率分配更像一个“执行指挥官”,关注如何将总任务高效、公平、安全地分解到每个士兵(PCS/电池簇);而充放电策略则像“总参谋长”,基于战场情报(市场、电网、自身状态)制定最优的作战计划。AI强化学习策略:让EMS通过与复杂环境不断交互,自主学习最优策略,适应不确定性。数字孪生与仿真:在虚拟空间中提前验证策略,评估风险,实现预防性控制。跨站协同优化:多个储能站的EMS通过云平台协同,参与区域电网甚至跨省市场的联合优化调度。

小帽子的博客 376

java语言使用ffmpeg在windows系统中实现视频推流拉流

本文主要详细介绍在windows系统下,采用java语言来实现rtmp流媒体协议的视频的推流拉流。利用screen capturer recorder录屏工具结合ffmpeg.exe文件捕获桌面视频流并推到nginx服务器,随后使用浏览器进行视频流的拉取并播放。文末给出相关工具的下载链接。

weixin_42684368的博客 2893

深入C6678启动流程:从BootRom参数表到多核镜像部署的完整解析

本文深入解析TMS320C6678 DSP的启动流程,从BootRom参数表到多核镜像部署的全过程。详细介绍了七种启动模式的工程选择、多核镜像构建技巧以及二级引导策略,帮助开发者掌握C6678的启动机制与调试方法,提升嵌入式系统开发效率。

weixin_30505225的博客 612

hspice2016安装教程

试装系统:win10 64bit 安装包路径和安装路径最好都不要出现中文,一般选择默认安装在C盘。 1.解压安装包压缩文件。 2.以管理员身份运行hspice_vL-2016.03-2_win.exe。 3.点击“Next”。 4.选择“I accept”,然后点击“Next”。 5.点击“Next”。 6.一般默认安装路径即可,然后点击“Next”。 7.点击“Next”. 8.点击“Next”。 9.正...

谢谢关注“小鱼教你模数电”,各平台同号 1万+

使用Kotlin/Compose构建的气候数据可视化开源项目 —— ClimateTraceKMP

使用Kotlin/Compose构建的气候数据可视化开源项目 —— ClimateTraceKMP 项目介绍 ClimateTraceKMP 是一个以Kotlin/Compose为基础的多平台项目,旨在展示来自climatetrace.org的相关气候变化排放数据。该项目正处于积极开发阶段,目前主要展示了按国家分部门的排放数据,未来还有更多数据可供探索。借助Kotlin/Compose的强大功能,...

gitblog_00062的博客 514

UDS $27服务DLL文件生成

UDS 27算法 DLL文件生成

hkj8808的博客 1283

Compose Multiplatform 实战:联机五子棋

1. 认识 Compose Multiplatform Jetpack Compose 作为 Android 端的新一代UI开发工具,得益于 Kotlin 优秀的语法特性,代码写起来十分简洁,广受开发者好评。作为 Kotlin 的开发方,JetBrains 在 Compose 的研发过程中也给与了大量帮助,可以说 Compose 是 Google 和 JetBrains 合作的产物。 在参与合作的过程中,JetBrains 也看到了 Compose 在跨平台方面的潜力,Compose 良好的分层设计使得

移动端开发干货分享 1万+

谷粒商城篇章9 ---- P248-P261/P292-P294 ---- 消息队列【分布式高级篇六】

RabbitMQ消息队列、RabbitMQ延时队列。

weixin_48568302的博客 1550

MediaPipe实战:从零构建人脸关键点检测应用

本文详细介绍了如何使用Google的MediaPipe框架从零构建一个实时人脸关键点检测应用。文章深入剖析了MediaPipe的三段式检测流水线,提供了Android平台的完整实战教程,包括环境配置、模型加载、摄像头集成、关键点绘制以及性能调优指南,帮助开发者快速实现高效、跨平台的人脸AR特效与交互功能。

weixin_29100927的博客 343

KMM 、 Compose 、 Flutter “神仙打架”?了解下现状

今天这篇文章的内容更多的科普性质而非技术行,主要是针对目前 KMM 、Compose 和 Flutter 的现状做一个陈述,其实很多时候它们之间并不冲突,但是作为开发者很经常就像开头一样,用“对立”的角度来看 A 火了 B 就要挂,这种心态大可不必。另外,「我更喜欢“百花齐放”的氛围,当然你也可以万花丛中只取一朵,所以不必过于焦虑,需要什么就用什么就可以」,技术服务于业务,就像我接触到的很多开发,他们需要使用什么技术并不是自己能决定的。❝。

chuyouyinghe的专栏 1049

从工创赛实战到开源:一个高鲁棒性智能物流视觉系统的构建与优化

本文分享了从工创赛实战中构建高鲁棒性智能物流视觉系统的完整经验。针对赛场复杂光线环境,详细阐述了摄像头选型、基于CLAHE和形态学梯度的抗干扰色环识别算法、卡尔曼滤波状态估计以及多线程串口通讯与任务调度等核心优化策略,旨在打造一个稳定可靠的视觉系统,并已将相关代码开源。

weixin_29046035的博客 321

Kotlin Compose Multiplatform下导航解决方案

其实笔者在写这篇文章的时候,KMP已经有实验性的导航解决方案了,官方文档中有介绍,而且使用起来也比较简单,可以参考我构建的的样例的这个分支但是目前版本由于是实验性的,不支持深层链接,而且返回手势只有安卓支持,甚至这些都不是最重要的,最大问题在于:笔者在使用这个导航的时候发现,官方导航组件在安卓环境下,有小概率会触发错误的过渡效果,原因不明,即使不设置任何动画效果,也有小几率触发,而且这个问题只在安卓条件下会出现,所以目前版本的建议还是使用比较成熟的外部导航组件。

AsterCass的博客 2338

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

使用共享 MVI 架构实现高效的 Kotlin Multiplatform Mobile (KMM) 开发

文章中探讨了 Google 提供的应用架构指南在多平台上的实现。通过共享视图模型(View Models)和共享 UI 状态(UI States),我们可以专注于在原生端实现 UI 部分。使用了简单的自定义抽象层,包括 KmmViewModel 和 KmmStateFlow,使得我们可以将共享的业务逻辑连接到原生 UI,而无需依赖于复杂的第三方库。这种方法有助于简化 KMM 开发,提高开发效率。Google官方应用架构指南hl=zh-cn。

虎哥LoveDroid 1401

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

使用KMP(kotlin多平台)在windows上出现:Cannot locate tasks that match ‘:composeApp:compileJava‘ as task ‘compil

kotlin 多平台在windows上运行失败解决方案

Ung8023 1400

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

上一篇: compose navigation 自定义navtype
下一篇: compose.material3 中的DatePicker在 desktop 平台同样可以适用
lynn8570_blog
博客等级 码龄10年 254粉丝 87原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值