使用NTKO插件
这玩意能不用就别用,因为它是插件,局限性比较大,在无法预知的用户环境上,各种问题。。。
但是在安全上做的比较好,不会在用户本地缓存临时文件等,都是在内存中操作,然后流传输,,,over
浏览器判断
computed: {
browser() {
const userAgent = navigator.userAgent
const rMsie = /(msie\s|trident.*rv:)([\w.]+)/
const rFirefox = /(firefox)\/([\w.]+)/
const rOpera = /(opera).+version\/([\w.]+)/
const rChrome = /(chrome)\/([\w.]+)/
const rSafari = /version\/([\w.]+).*(safari)/
const uaMatch = (ua) => {
let match = rMsie.exec(ua)
if (match != null) {
return { browser: 'IE', version: match[2] || '0' }
}
match = rFirefox.exec(ua)
if (match != null) {
return { browser: match[1] || '', version: match[2] || '0' }
}
match = rOpera.exec(ua)
if (match != null) {
return { browser: match[1] || '', version: match[2] || '0' }
}
match = rChrome.exec(ua)
if (match != null) {
return { browser: match[1] || '', version: match[2] || '0' }
}
match = rSafari.exec(ua)
if (match != null) {
return { browser: match[2] || '', version: match[1] || '0' }
}
if (match != null) {
return { browser: '', version: '0' }
}
}
return uaMatch(userAgent.toLowerCase())
}
}
DOM
classid,codebase这些是在ntko插件包里面有的,放在data里面就行
async initWebDomOffice() {
const browser = this.browser.browser
let domStr = '<object id="TANGER_OCX" '
if (browser === 'IE') {
if (window.navigator.platform === 'Win32') {
domStr += ' classid="clsid:' + this.classid + '" codebase="' + this.codebase + '" '
domStr += ' width="' + this.width + '" height="' + this.height + '"> '
domStr += ' <param name="MakerCaption" value="' + this.MakerCaption + '"> '
domStr += ' <param name="MakerKey" value="' + this.MakerKey + '"> '
domStr += ' <param name="ProductCaption" value="' + this.ProductCaption + '"> '
domStr += ' <param name="ProductKey" value="' + this.ProductKey + '"> '
domStr += ' <param name="NoExpireKey" value="' + this.NoExpireKey + '"> '
domStr += ' <param name="IsUseUTF8URL" value="-1"> '
domStr += ' <param name="IsUseUTF8Data" value="-1"> '
} else if (window.navigator.platform === 'Win64') {
domStr += ' classid="clsid:' + this.classid64 + '" codebase="' + this.codebase64 + '" '
domStr += ' width="' + this.width + '" height="' + this.height + '"> '
domStr += ' <param name="MakerCaption" value="' + this.MakerCaption + '"> '
domStr += ' <param name="MakerKey" value="' + this.MakerKey + '"> '
domStr += ' <param name="ProductCaption" value="' + this.ProductCaption + '"> '
domStr += ' <param name="ProductKey" value="' + this.ProductKey + '"> '
domStr += ' <param name="NoExpireKey" value="' + this.NoExpireKey + '"> '
domStr += ' <param name="IsUseUTF8URL" value="-1"> '
domStr += ' <param name="IsUseUTF8Data" value="-1"> '
}
} else if (browser === 'chrome') {
domStr += ' type="application/ntko-plug"'
domStr += ' width="' + this.width + '" height="' + this.height + '"'
domStr += ' clsid="{' + this.classid + '}" codebase="' + this.codebase + '"'
domStr += ' ForOnAfterOpenFromURL="AfterOpenFromURL"'
domStr += ' ForOnFileCommand="OnFileCommand"'
domStr += ' ForOnDocumentOpened="OnDocumentOpened"'
domStr += ' ForOnDocumentClosed="OnDocumentClosed"'
domStr += ' ForOnSaveToURL="OnSaveToURL"'
domStr += ' _IsUseUTF8URL="-1"'
domStr += ' _IsUseUTF8Data="-1"'
domStr += ' _WebUserName="' + this.userName + '"'
domStr += ' _MakerCaption="' + this.MakerCaption + '"'
domStr += ' _MakerKey="' + this.MakerKey + '"'
domStr += ' _ProductCaption="' + this.ProductCaption + '"'
domStr += ' _NoExpireKey="' + this.NoExpireKey + '"'
domStr += ' _ProductKey="' + this.ProductKey + '">'
} else {
return this.setNotSupportAtt('Sorry,NTKO文档控件暂不支持其他浏览器!')
}
domStr += '<div style="' + this.tipStyle + '">'
domStr += '<span style="color:#F86C11;">尚未安装ntko office文档控件浏览器插件!</span></br>'
domStr += '<a style="color:#4762FE;" target="_blank" class="pl20" href="/tools/NTKO-install.exe">点击此处下载!</a>'
domStr += '</div></object>'
this.initOfficeSetting(domStr)
}
初始化
initOfficeSetting(domStr) {
if (this.isView) {
return this.viewFileOnline(this.routerParams.attId, this.routerParams.source)
}
// 该控件只支持office类的文档,这里就是一个控制
if (!this.attInfo['attType'] || this.openTypes.indexOf(this.attInfo['attType'].toLowerCase()) < 0) {
return this.setNotSupportAtt(`暂不支持非Office文档在线编辑!当前附件格式为:${this.attInfo['attType']}`)
}
document.getElementById('ntko').innerHTML += domStr
this.$nextTick(() => {
const TANGER_OCX = document.getElementById('TANGER_OCX')
TANGER_OCX.FileSave = false
TANGER_OCX.FileNew = false
TANGER_OCX.FileOpen = false
TANGER_OCX.FileSaveAs = false
TANGER_OCX.FilePageSetup = false
TANGER_OCX.FilePrint = false // 打印
TANGER_OCX.FilePrintPreview = false // 打印预览
TANGER_OCX.Caption = this.attInfo['fileName']
if (this.isView) {
// TANGER_OCX.IsNoCopy = true
TANGER_OCX.TitleBar = false // 是否显示标题栏
TANGER_OCX.RibbonBars = false // 是否显示OFFICE功能区
TANGER_OCX.ToolBars = false // 是否显示工具栏
TANGER_OCX.IsResetToolbarsOnOpen = false // 是否在打开文档之后重置工具栏为常用模式
TANGER_OCX.CustomToolBar = false // 自定义工具栏
TANGER_OCX.Menubar = false // 是否显示菜单栏
TANGER_OCX.IsShowToolMenu = false // 工具菜单
TANGER_OCX.IsShowHelpMenu = false // 帮助菜单
TANGER_OCX.IsShowInsertMenu = false // 插入菜单
TANGER_OCX.IsShowEditMenu = false // 编辑菜单
TANGER_OCX.FilePageSetup = false // 文件菜单的页面设置项
TANGER_OCX.FileProperties = false // 文件菜单的属性项
TANGER_OCX.IsEnableDoubleClickFSM = false // 是否允许双击切换全屏
}
// pdf 是需要单独处理的
try {
if (this.attInfo['attType'].toLowerCase() === '.pdf') {
if (this.isWin64) {
TANGER_OCX.AddDocTypePlugin('.pdf', 'PDF.NtkoDocument', '4.0.2.0', '/ntko/ntkooledocallx64.cab', 51, true)
} else {
TANGER_OCX.AddDocTypePlugin('.pdf', 'PDF.NtkoDocument', '4.0.2.0', '/ntko/ntkooledocall.cab', 51, true)
}
}
// AddHTTPHeader只针对IE浏览器生效,这里的请求后端做了不验证header
TANGER_OCX.AddHTTPHeader('Authorization:' + this.$cookie.get('token'))
TANGER_OCX.IsShowOpeningDocUI = false
// 后端返回文件流就行
TANGER_OCX.BeginOpenFromURL(`/storeApi/ntko/view?id=${this.routerParams.attId}`, true, false)
} catch (e) {
console.log('加载NTKO发生错误,请检查是否安装!')
}
})
}
事件
触发
不管是ie浏览器还是其他浏览器,都需要找到入口的html文件,一般都是index.html,写触发事件方法
<!-- 以下为Chrome浏览器接管事件 -->
<script type="text/javascript">
// 菜单操作
function OnFileCommand(cmd) {
document.getElementById('ntko').onFileCommand(cmd)
}
// 打开文档
function OnDocumentOpened() {
document.getElementById('ntko').onDocumentOpened()
}
// 关闭文档
function OnDocumentClosed() {
document.getElementById('ntko').onDocumentClosed()
}
// 保存成功后回调
function OnSaveToURL(type, code, res) {
document.getElementById('ntko').onSaveToURL(code, res)
}
</script>
<!-- 以下为IE浏览器接管事件 -->
<script language="Jscript" for="TANGER_OCX" event="OnFileCommand(cmd)" >
document.getElementById('ntko').onFileCommand(cmd)
</script>
<script language="Jscript" for="TANGER_OCX" event="OnDocumentOpened()" >
document.getElementById('ntko').onDocumentOpened()
</script>
<script language="Jscript" for="TANGER_OCX" event="OnDocumentClosed()" >
document.getElementById('ntko').onDocumentClosed()
</script>
然后回到vue的文件中
initDefaultDomFunction() {
document.getElementById('ntko').onDocumentOpened = () => {
// todo
}
// 0 新建 1 打开 2 关闭 3 保存
document.getElementById('ntko').onFileCommand = (type) => {
// todo
}
document.getElementById('ntko').onDocumentClosed = () => {
// todo
}
document.getElementById('ntko').onSaveToURL = (code, res) => {
// todo
}
}
有个比较坑的点 saveToURL
这个方法的返回值,在IE中是同步返回的,但是其他浏览器需要添加个回调方法,就是上面的 OnSaveToURL
const result = TANGER_OCX.saveToURL('/storeApi/ntko/save', 'upLoadFile', 'fileName', 0, false)
if (this.browser.browser === 'IE') {
if (!result) {
return TANGER_OCX.ShowTipMessage('提示', '附件保存失败!')
}
document.getElementById('ntko').onSaveToURL(0, result)
}
跳转到
if (this.attInfo['fileType'].toLowerCase() === '.pdf') {
TANGER_OCX.ActiveDocument.GotoPage(5)
} else {
TANGER_OCX.ActiveDocument.Application.selection.Goto(1, 1, 5)
}
设置只读,ppt无法设置只读模式
try {
if (['.doc', '.docx'].indexOf(this.attInfo['attType'].toLowerCase()) > -1) {
TANGER_OCX.ActiveDocument.Protect(3, false)
} else if (['.xls', '.xlsx'].indexOf(this.attInfo['attType'].toLowerCase()) > -1) {
TANGER_OCX.ActiveDocument.Application.ActiveWorkbook.Protect('', true)
TANGER_OCX.ActiveDocument.Application.ActiveSheet.Protect('', true, true, true)
} else {
TANGER_OCX.SetReadOnly(true)
}
} catch (error) {
console.log('文档进入只读模式失败!', error)
}
设置修订模式
TANGER_OCX.ActiveDocument.TrackRevisions = true // 控制是否进入修订模式
TANGER_OCX.ActiveDocument.ShowRevisions = true // 设置是否显示痕迹
TANGER_OCX.ActiveDocument.Application.ActiveWindow.View.ShowRevisionsAndComments = true
TANGER_OCX.ActiveDocument.Application.ActiveWindow.View.RevisionsView = 0
NTKO自带浏览器
这个其实就是IE浏览器,但是它实现了自己的一些东西,比较方便,但是测试贼蛋疼,没有F12,而且对vue框架不太好,因为IE嘛,你知道的,低版本就凉了。。。
const ntkoBrowser = require('@/utils/ntkobackground.min.js').ntkoBrowser
const ntkoed = ntkoBrowser.ExtensionInstalled()
if (!ntkoed) {
ntkoBrowser.openWindow(`/file#/ntko/${params.attId}`)
} else {
return this.$notify.info('sorry!')
}
不过它里面有用到postMessage,这个挺好的,如果新打开一个窗口,操作后关闭该窗口,刷新原窗口数据,咱也可以用这个
window.opener.postMessage({ type: 'ntko_save_success' })
window.addEventListener('message', ({ data }) => {
if (data && data.type === 'ntko_save_success') {
// todo
}
}, false)