基于isSpring的PPT转换

背景

PPT课件目前还是一项在教学中高度频繁使用的工具,对于在线教学就更为重要了。如何把PPT转换为在线web,同时保留更多的PPT特性(动画、音效、视频)呢?这里介绍一种基于iSpring的PPT转换工具。用以解决在线PPT的这一困境。

通过官网,我们可以看到它有iSpring Suite和iSpring CodeBuilder ,这两者有什么区别呢?前者主要用于PowerPoint插件,会以tab的形式显示在PowerPoint中,后者是一个开发工具,允许开发人员使用 iSpring API 进行二次开发。它提供了编程接口,开发者可以利用它来集成和定制 iSpring 内容,或者将内容嵌入到自定义的 LMS 或其他系统中。

环境准备

ispring本身是一个exe程序,执行安装后即可使用。本身是付费的,有需要Pojieban用以学习研究的可以联系我。

依赖环境

  • Windows 64 位环境
  • 系统已安装 Office(2013 版本或更高,其它版本未验证)

安装

  1. 运行工程目录 ispring 目录下的 ispring_platform_ultimate_x64_8_3_0.msi 安装包安装转换 SDK。

pojie大法

  1. 安装完成后使用 ispring 目录下的 iSpringSDK.dll 文件替换掉 SDK 安装安装目录下的同名文件。SDK 安装目录默认在 C:\Program Files\iSpring\Platform Ultimate 8\PPT Conversion SDK
  2. 打开 ispring SDK 编辑器,编辑器文件目录默认为 C:\Program Files\iSpring\Platform Ultimate 8\PPT Conversion SDK\CodeBuilder\CodeBuilder.exe,在编辑器最后一个 Tab Activation 中输入工程目录中 ispring/key.txt 中的 key 进行激活即可。
  3. 将工程目录 ispring/players 文件目录拷贝覆盖到 SDK 安装目录 players 下,默认为 C:\Program Files\iSpring\Platform Ultimate 8\PPT Conversion SDK\players

常规使用

找到安装目录下的CodeBuilder.exe(win10环境默认路径为C:\Program Files\iSpring\Platform Ultimate 8\PPT Conversion SDK\CodeBuilder\CodeBuilder.exe),选择对应ppt文件进行转化,OutputOptions选HTML5,

miscellaneous settings→javascript api 这个两个勾要选上,否则无法和webview进行交互,教师端没法进行切页。

另外,如果文件做了修改,那需要重新选择sourceFile,不然转出来的还是上一个文件。

自动化转换

除了通过界面使用之外,还提供了几种调用方式C#、VB.NET、CMD。为了做好自动化,我们可以通过nodejs调用cmd的方式实现。

iSpringSDK.exe c -fs --skin none "C:\Users\admin\Desktop\新建 Microsoft PowerPoint 演示文稿 (2).pptx" "C:\Users\admin\Desktop\PowerPoint 演示文稿\新建 Microsoft PowerPoint 演示文稿 (2).html" 

因此,我们可以把会变的部分做成变量,实现自动化转换

const fs = require('fs');
const { exec } = require('child_process');
const archiver = require('archiver');
const axios = require('axios');
const path = require('path');

// 配置文件路径和上传 URL
const pptFilePath = 'path/to/your.pptx';
const outputPdfPath = 'output/your.html';
const zipFilePath = 'output/your.zip';
const uploadUrl = 'https://your-upload-server.com/upload';

// 1. 将 PPT 转换为 PDF
function convertPptToPdf() {
    return new Promise((resolve, reject) => {
        const command = `iSpringSDK.exe c -fs --skin none ${pptFilePath} ${outputPdfPath} `;
        exec(command, (error, stdout, stderr) => {
            if (error) {
                console.error(`转换失败: ${error.message}`);
                return reject(error);
            }
            console.log('PPT 转换成功');
            resolve(outputPdfPath);
        });
    });
}

// 2. 压缩文件
function zipFile(filePath) {
    return new Promise((resolve, reject) => {
        const output = fs.createWriteStream(zipFilePath);
        const archive = archiver('zip', { zlib: { level: 9 } });

        output.on('close', () => {
            console.log(`文件已压缩: ${archive.pointer()} bytes`);
            resolve(zipFilePath);
        });

        archive.on('error', (err) => reject(err));

        archive.pipe(output);
        archive.file(filePath, { name: path.basename(filePath) });
        archive.finalize();
    });
}

// 3. 上传文件
function uploadFile(filePath) {
    const fileStream = fs.createReadStream(filePath);
    const formData = new FormData();
    formData.append('file', fileStream);

    return axios.post(uploadUrl, formData, {
        headers: formData.getHeaders()
    })
    .then(response => {
        console.log('上传成功:', response.data);
        return response.data;
    })
    .catch(error => {
        console.error('上传失败:', error);
        throw error;
    });
}

// 主函数:执行转换、压缩、并上传
async function main() {
    try {
        // 转换 PPT 到 PDF
        await convertPptToPdf();

        // 压缩 PDF
        await zipFile(outputPdfPath);

        // 上传 ZIP
        await uploadFile(zipFilePath);
    } catch (error) {
        console.error('流程中出现错误:', error);
    }
}

main();

业务落地

PPT转换之后,我们就得到了一个如下所示的html页面

配置相关的数据已经被压缩到这个加密的字符串里了

data下可以看到PPT所使用的字体文件、图片、音视频等,以及每个ppt页的样式和代码

那我们就可以把它应用到业务中了。可以通过在线的显示或者离线包的方式加载。

如果是做直播场景,可能会遇到需要用代码控制PPT跳转的情况。这时候,我们需要增加获取player实例的代码,如下所示:

(function(player)
{
 function findConnector(win)
 {
  var retries = 0;
  while (!win.ispringPresentationConnector && win.parent && win.parent != win)
  {
   ++retries;
   if (retries > 7)
   {
    return null;
   }

   win = win.parent;
  }
  return win.ispringPresentationConnector;
 }

 function getConnector()
 {
  var api = findConnector(window);
  if (!api && window.opener && (typeof(window.opener) != "undefined"))
  {
   api = findConnector(window.opener);
  }
  return api;
 }

 var connector = getConnector();
 if (connector)
 {
  connector.register(player);
 }
})(player);

拿到player实例,可以获取playbackController对象控制PPT的跳转了。

let $playbackController = player.view().playbackController() // 生成ppt实例化对象

// 当前页
const currentSlideIndex = $playbackController.clock().timestamp().slideIndex()

// 当前状态
const state = $playbackController.playbackState()
console.info('ppt状态:', { state, slideIndex: currentSlideIndex })

// 特定跳转
// slideIndex: 数字类型,幻灯片索引 stepIndex: 数字类型,动画步骤索引 timeOffset:数字类型, 从目标动画步骤开始的时间偏移,以秒为单位,默认需要传递0 autoPlay:布尔类型,是否自动播放动画,默认需要传递true
$playbackController.gotoTimestamp(slideIndex, stepIndex, timeOffset, autoPlay)

// 下一页
$playbackController.gotoNextSlide(autoPlay)

// 上一页
$playbackController.gotoPreviousSlide(autoPlay)

// 播放动画
$playbackController.play()

// 暂停动画
$playbackController.pause()

// 跳转特定页码
$playbackController.gotoSlide(slideIndex)

// 事件监听
 this.$slideChangeEventInstance = this.$playbackController.slideChangeEvent()
this.$slideChangeEventInstance.addHandler(this.onSlideChangeEvent)

this.$stepChangeEventInstance = this.$playbackController.stepChangeEvent()
this.$stepChangeEventInstance.addHandler(this.onStepChangeEvent)

this.$stateChangeEventInstance = this.$playbackController.clock().stateChangeEvent()
this.$stateChangeEventInstance.addHandler(this.onClockStateChangeEvent)

iSpring支持自定义播放器样式,如果默认的样式不满足业务,可以定制样式。

在真实的落地场景中,我们也遇到了一些坑:

  • wps制作的文件,可能会出现黑屏或者转出来文件特别大的情况
  • 安卓、ios下第一次打开,部分机型会出现一个播放按钮,需要点击一下才可以开始使用
  • 不分机型对于音视频的播放存在不播放的情况
  • 文件过大,容易出现视频丢失

总结

作为一个PPT转换功能,能还原到这个程度,实属不易了。虽然有一些坑,但整体使用效果还是不错的,新版本的坑会少一些,建议使用新版本。

本文由mdnice多平台发布

相关推荐
ZhaiMou12 分钟前
HTML5拖拽API学习 托拽排序和可托拽课程表
前端·javascript·学习·html5
code_shenbing3 小时前
跨平台WPF框架Avalonia教程 三
前端·microsoft·ui·c#·wpf·跨平台·界面设计
白臻4 小时前
使用element-plus el-table中使用el-image层级冲突table表格会覆盖预览的图片等问题
前端·vue.js·elementui
北极糊的狐4 小时前
vue使用List.forEach遍历集合元素
前端·javascript·vue.js
晓看天色*4 小时前
[JAVA]MyBatis框架—获取SqlSession对象
java·开发语言·前端
ZVAyIVqt0UFji4 小时前
Reactflow图形库结合Dagre算法实现函数资源关系图
开发语言·前端·javascript·ecmascript
luckilyil5 小时前
前端—Cursor编辑器
前端·编辑器
cooldream20095 小时前
快速上手 Vue 3 的高效组件库Element Plus
前端·javascript·vue.js·element plus
我是苏苏5 小时前
Web开发:ORM框架之使用Freesql的DbFrist封装常见功能
java·前端·jvm
疯狂的沙粒5 小时前
Vue项目开发 vue实例挂载的过程?
前端·javascript·vue.js