PDF、Word、Excel文件前端预览实操干货都在这!

news2025/1/22 16:12:43

随着Odoo在各个行业领域的深入应用,对Odoo的前端交互体验要求也越来越高。

我们在项目开发中常常会遇到,需要上传文件并预览的问题。

这里是我遇到的需求,并完成的一个小demo。

在Odoo中实现文件上传 

首先我们需要在qweb页面中加入上传的xml

<div style="width: 1200px; margin-top:10px;margin-right: 52px; display: flex; height: 28px; line-height: 28px">
<!-- 展示已选文件的位置-->
    <span style="width:70px;font-weight:bold;">附件 </span>
    <div class="uploader_file_box">
 
    </div>
<!-- 上传部分-->
    <div class="uploader_input">
        <label class="fa fa-plus btn btn-white-up" style="font-weight:bold;" for="fileinput"> 选择上传附件</label>
        <input id="fileinput" class="uploader-file-input" type="file" multiple="multiple" value="Select Files"></input>
    </div>
 
</div>

#  css部分 

/*上传文件按钮*/
.uploader_input{
    width: 120px;
 
}
.uploader-file-input{
    display: none;
}
/*上传文件展示位置*/
.uploader_file_box{
    display: flex;
}
.uploader__file-list__item{
    padding:0 1rem;
    display: flex;
    background-color: #dfdfdf;
    margin-right: 10px;
}
.btn-white-up{
    background-color: #fff;
    border: 1px dashed #cccccc ;
}
.uploader__file-list__text{
     max-width: 100px;
    padding-right: 10px;
     display: inline-block;
     white-space: nowrap;
     overflow: hidden;
     text-overflow: ellipsis;
 }
.uploader__file-list__text:hover{
    color: #478aee;
}
.js-upload-remove-button{
    cursor: pointer;

在完成css部分后,我们在项目的页面上会得到一个这样的上传组件 ⬇ 

 

 

#  js部分上传的事件及监听

点击选择上传附件后,会调用默认的input的上传功能,并给输入框监听change事件,拿到上传的文件。

this.$buttons.find('#fileinput').on('change', this.proxy("selectFile")) //读取上传的文件

#  开始上传文件start 

//当前页面全局定义的
var fileOption={
    fileTypeWhiteList: [ 'ppt','pptx', 'xls','xlsx','pdf','doc','docx'],//校验的格式
}
var fileState = {
    fileBatch:[],
    fileListIndex:0
}
var upfilelength=0;
 
 
//文件上传 start
// 获取文件
selectFile:function (e){
     e.preventDefault();
     e.stopPropagation();
     //这里可以加一个校验
     var files = e.target.files || e.dataTransfer.files || e.dataTransfer.getData;
     for (var i = 0; i < files.length; i++) {
         Self.addfile(files[i]);
     }
 
},
//上传文件
addfile:function (file){
    let self = this;
    var fileSize = file.size;
    //判断文件大小
    if( parseInt(fileSize/1024/1024)>=20){
        this.displayNotification({
             title: "系统提示",
             message: '单个文件上传不能超过20MB',
             type: 'danger',
             sticky: false
        });
        return
    }
    var upfiles = file;
    if (fileOption.fileTypeWhiteList.indexOf((this.getExtension(file.name)).toLowerCase()) !== -1) {
        framework.blockUI()//调用loading....
        //调用接口并在上次完成后调用查询接口查询到上传了的文件
        self.getUpdataList();
        })
    } else {
         // 不在提示文件不可上传
         let mesg = '不支持该格式的文件,请上传以下格式的文件ppt,pptx,xls,xlsx,pdf,doc,docx;'
         Self.displayNotification({
             title: "系统提示",
             message: mesg,
             type: 'danger',
             sticky: false
         });
         return
    }
 
 
},
//反显上传的数据
//我这里是调用接口去查询上传后的数据
getUpdataList:function (){
    let self = this;
    //先清除后加
    $('#fileinput').val('');
    $('.uploader_file_box').children().remove();
    this._rpc({
        route: 'xxxxxxx',
        params:{
           xxxx:xxxxx,
        }
    }).then(res=>{
        var upfileList = res.data;
        if(upfileList.length>0){
            approveFileFlag = false;
            upfilelength = upfileList.length;
            for (let i = 0; i <upfileList.length; i++) {
                let fileItem = upfileList[i];
                self.files_show(fileItem)
            }
        }else{
            approveFileFlag = true;
            $('.uploader_file_box').children().remove();
        }
        console.log(res,'已上传的文件')
    })
},
//页面渲染上传的文件展示js创建以上传的文件
files_show:function (file){
    var fileName = file.name;
    var fileId = file.id;
    var filesdow = file.local_url
    var fileNameWrapper = $('<span class="uploader__file-list__text" title="'+fileName+'">'+ '<a href="'+filesdow+'" download="'+fileName+'" target="view_window">'+fileName+'</a>' +'</span>');//文件名称
    fileState.fileListIndex++;
    //创建一个放入的
    var listItem = $('<li class="uploader__file-list__item" data-index="' + fileId + '"></li>');//文件展示的每一条的盒子
    var removeLink = $('<span class="uploader__file-list__button"><i class=" js-upload-remove-button fa fa-close" data-index="' + fileId + '"></i></span>');
    fileState.fileBatch.push({filesdow: filesdow, id: fileId, fileName: fileName,});//保存文件
    //校验是否需要删除,校验部分,根据自己的需求,自己去调整
    if(quot_status==0&&(!approve_type)){
        listItem.append(fileNameWrapper).append(removeLink);
    }else {
        listItem.append(fileNameWrapper);
 
    }
    $('.uploader_file_box').append(listItem);
    this.bindEvents();
},
//挂载事件的方法因为解决查询多次已上传文件时删除文件事件的触发问题
bindEvents:function (){
    //先集体移然后集体添加
    $('.js-upload-remove-button').unbind("click");
    //在集体添加事件
    $('.js-upload-remove-button').on('click',this.removeItemHandler);
 
},
//删除已上传的文件,待确认
removeItemHandler:function (e){
    let self = this;
    e.preventDefault();
    var removeIndex = $(e.target).data('index');
    Dialog.confirm(self, '确定删除?', {
        title: '提示',
        confirm_callback: function () {
            Self.removeItem(removeIndex);
            $(e.target).parent().parent().remove();
        },
    })
 
},
//删除上传的数据
removeItem(id){
    let self = this;
    let removId = id;
    this._rpc({
        route: '/xxxx/xxxxdel',
        params:{
            xxxid:xxxx
        }
    }).then(res=>{
         self.displayNotification({
             title: "系统提示",
             message: res['msg'],
             type: 'success',
             sticky: false
         });
         self.getUpdataList();//删了后要查询并反显数据
    })
    //这部分是做多数据一次上传需要我这边没用到
    for (var i = 0; i < fileState.fileBatch.length; i++) {
        if (fileState.fileBatch[i].id === parseInt(id)) {
            fileState.fileBatch.splice(i, 1);
            break;
        }
    }
},
//规则校验
getExtension:function(path){
    var basename = path.split(/[\\/]/).pop();
    var pos = basename.lastIndexOf('.');
 
    if (basename === '' || pos < 1) {
        return '';
    }
    return basename.slice(pos + 1);
},
//文件上传end

完成文件上传后,接下来就是重头部分——文件的预览。

文件预览分为两种情况,在Odoo中,其实PDF的文件是可以直接预览的,而Excel、Word、txt等文件格式则不行,那么如何解决这个问题呢?

在Odoo中实现不同文件预览 

# 引入对应的js组件

预览文件,需要使用到外部的js相关组件库:

https://officetohtml.js.org/  组件方案来源

能够开源的,目前只支持docx和xlsx等相关原生Office的预览功能,我们可以去官网的GitHub 上下载。

在这里,我们需要在引入文件的地方引入对应的js部分 ⬇

 

<!--PDF-->
<link rel="stylesheet" href="/quotation/static/src/js/include/pdf/pdf.viewer.css"/>
<script src="/quotation/static/src/js/include/pdf/pdf.js"></script>
<!--Docs-->
<script src="/quotation/static/src/js/include/docx/jszip-utils.js"></script>
<script src="/quotation/static/src/js/include/docx/mammoth.browser.min.js"></script>
<!--All Spreadsheet -->
<link rel="stylesheet" href="/quotation/static/src/js/include/SheetJS/handsontable.full.min.css"/>
<script type="text/javascript" src="/quotation/static/src/js/include/SheetJS/handsontable.full.min.js"></script>
<script type="text/javascript" src="/quotation/static/src/js/include/SheetJS/xlsx.full.min.js"></script>
<!--Image viewer-->
<link rel="stylesheet" href="/quotation/static/src/js/include/verySimpleImageViewer/css/jquery.verySimpleImageViewer.css"/>
<script type="text/javascript" src="/quotation/static/src/js/include/verySimpleImageViewer/js/jquery.verySimpleImageViewer.js"></script>
<!-- officeToHtml-->
<script src="/quotationmail.DocumentViewer/static/src/js/include/officeToHtml/officeToHtml.js"></script>
<link rel="stylesheet" href="/quotation/static/src/js/include/officeToHtml/officeToHtml.css"/>

 对应的文件直接放到对应的js文件目录下即可。

需要注意的是,这个步骤需要在上面执行上传的js的前面进行置入,接下来就是点击文件后预览文件了。

# PDF、txt等文件预览的样式

这里预览的盒子css的样式就不写了,因为根据每个人的情况不同,所需的预览方式也不同。

下面分享的样式,修改了上面盒子点击事件后的js部分代码,因为我需要的是下载文件,用户在本地预览,所以增加的是a标签。

在实际应用中,可以去掉改写方法。

//挂载事件的方法
bindEvents:function (){
    //先集体移然后集体添加
    $('.js-upload-remove-button').unbind("click");
    //在集体添加事件
    $('.js-upload-remove-button').on('click',this.removeItemHandler);
    //添加文件的点击事件
    $('.uploader__file-list__text').unbind("click");
    $('.uploader__file-list__text').on('click',this.previewsShow)
},
// 预览
previewsShow:function (){
    // 点击时先获取是那个文件,并找到对应文件的url地址,
    var file_path = "path/to/file.pptx";
     
    // 先清除
    $('.body').remove('#resolte-contaniner')
    //在添加,或者可以先写到上面的xml中这样就不需要创建
    let previewbox = `<div id="resolte-contaniner"></div>`
    $('.body').append(previewbox);
     
    //读取远程文件对象时
    //可以预设不同文件的不同清空的预设
    $("#resolte-contaniner").officeToHtml({
        url: file_path,
        inputObjId: "select_file",
        pdfSetting: {
            setLang: "he",
            thumbnailViewBtn: true,
            searchBtn: true,
            nextPreviousBtn: true,
            pageNumberTxt: true,
            totalPagesLabel: true,
            zoomBtns: true,
            scaleSelector: true,
            presantationModeBtn: true,
            openFileBtn: true,
            printBtn: true,
            downloadBtn: true,
            bookmarkBtn: true,
            secondaryToolbarBtn: true,
            firstPageBtn: true,
            lastPageBtn: true,
            pageRotateCwBtn: true,
            pageRotateCcwBtn: true,
            cursorSelectTextToolbarBtn: true,
            cursorHandToolbarBtn: true
        }
    });
 
},

如:Execl预览后,图片如下⬇

 PDF 不做颜色,不用这个,只用原生的就可以了。

txt  的文件内容获取方式是在文件的file里。

然后通过reader.readAsText(file)就可以读取到txt的内容。同时,我们要对文件进行校验格式,以免用户上传时,文件格式的问题引发其他错误。

当然在这里,我们也可以在这个文件中,扩展或者改写文件触发的一些机制来实现不同的需求 ⬇

以上就是关于在Odoo上实现文件预览,单纯的前端解决方案,欢迎各位提出更好的解决方案! 

本期作者:神州数码云基地 沈童

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Chrome浏览器插件开发v3版本第二篇:改变页面布局案例

跟着官方教程走才是硬道理&#xff1a;https://developer.chrome.com/docs/extensions/mv3/getstarted/tut-focus-mode/ 老规矩&#xff0c;搭建基本的项目结构&#xff1a;创建一个manifest.json文件 {"manifest_version":3,"name":"Focus",&…

[附源码]Python计算机毕业设计宠物销售管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

SQL Server中row_number函数用法介绍

一、SQL Server Row_number函数简介 ROW_NUMBER()是一个Window函数&#xff0c;它为结果集的分区中的每一行分配一个连续的整数。 行号以每个分区中第一行的行号开头。 语法实例&#xff1a; select *&#xff0c;row_number() over(partition by column1 order by column2)…

PaddlePaddle飞浆搭建和机器学习文字识别

PaddlePaddle飞浆搭建和机器学习文字识别 文章转自&#xff1a;https://lingkang.top/archives/paddlepaddle-fei-jiang-da-jian-he-ji-qi-xue-xi-wen-zi-shi-bie 官网&#xff1a;https://www.paddlepaddle.org.cn/ 飞桨&#xff08;PaddlePaddle&#xff09;以百度多年的深…

第七章:Springmvc中applicationContext.xml配置文件应用上下文详解

主要配置程序的总体用上下文&#xff0c;让容器对全局掌握来龙去脉 1.扫描所有项目的包名 2.配置项目所有的静态资源映射 3.配置请求方法的映射驱动 4.配置适配器适配RequestMapping注解标注的Handler&#xff08;HandlerMethod类型&#xff09; 5.配置消息转换器决定浏览器以什…

Unity游戏Mod/插件制作教程04 - 如何创建配置文件

ConfigEntry<T> 在插件功能的设计中&#xff0c;经常会有需要玩家自己配置的东西&#xff0c;比如插件的各种设置&#xff0c;快捷键的分配等。在BepInEx中&#xff0c;提供了一个ConfigEntry类简化了配置操作。 我们来看一段示例&#xff1a; (注:由于阿B在代码页中会…

Docker的网络模式

一、Docker网络 1.1 Docker网络实现原理 docker 使用linux 桥接&#xff0c;在宿主机虚拟一个docker 容器网桥&#xff08;docker0) &#xff0c;docker 启动一个容器时会根据docker 网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker 网桥…

JAVA接入OPC DA2.0引发的问题

背景&#xff1a; JAVA接入OPC DA后&#xff0c;在生产环境跑了一段时间后就会出现异常&#xff0c;给折腾的够呛&#xff0c;起初的报错还能通过重启OPC连接解决&#xff0c;后来强制重新连接也不行&#xff0c;最终一套测试下来&#xff0c;除非重启OPC服务器&#xff0c;别…

生产制造企业数字化转型:流程制造ERP

ERP的含义是企业资源计划&#xff0c;含义是对企业所拥有各种资源进行综合规划和优化管理&#xff0c;用以降低成本&#xff0c;提高效率&#xff0c;增加利润。ERP最初是在90年代初提出的&#xff0c;那时的ERP概念&#xff0c;还只是根据计算机技术的发展和供需链管理,推论各…

[附源码]java毕业设计校园闲置物品租赁系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

深度学习——动物数据集大合集(附下载地址)

说明&#xff1a;部分数据收费&#xff0c;付费后数据请关注私信内容&#xff0c;会给出下载链接&#xff0c;亲测数据质量不错&#xff0c;如下图所示&#xff1a; ​ 1、30种常见鱼类数据集 数据集介绍&#xff1a;30种常见鱼类数据集&#xff08;每类鱼30-100张图片不等&am…

丰田+比亚迪「围攻」大众,明年或将「让出」榜首之位

大众&#xff0c;正在经历最艰难的时刻。 高工智能汽车研究院监测数据显示&#xff0c;今年1-10月&#xff0c;大众集团旗下大众品牌乘用车在中国市场的交付上险同比下滑11.5%&#xff0c;而作为老对手&#xff0c;排名第二的丰田&#xff0c;则是同比增长13.72%。 豪华品牌部…

Oracle快速入门 | 黑马

简介 概述 Oracle目前使用最广的大型数据库管理系统&#xff0c;作为分布式数据库实现分布式处理功能。 广泛用于金融行业&#xff0c;大量数据而且需要很安全 特点 支持多用户&#xff0c;大事务量的事务处理数据安全性和完整性控制&#xff08;主要卖售后的&#xff0c…

信息安全工程实践笔记--Day1 信息收集漏洞扫描

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录实验目标&#xff08;一&#xff09;信息收集一、搜索引擎二、域名1.whois 查询2.子域名查询3.真实ip(1)什么是cdn&#xff1f;(2) 如何验证目标服务器是否挂载cdn&a…

吴恩达-机器学习-k-means聚类算法

目录 吴恩达-机器学习2022版 k-means聚类算法实现整理 1.核心函数四个&#xff1a; 1.find_closest_centroids &#xff1a;寻找最近的质心 2.compute_centroids &#xff1a;迭代重新计算质心 3.kMeans_init_centroids &#xff1a;随机初始化质心 4.run_kMean…

Centos安装Rclone,操作Minio基本命令

简介 Rclone 是一个用于和同步云平台同步文件和目录命令行工具。它允许在文件系统和云存储服务之间或在多个云存储服务之间访问和同步文件&#xff0c;它具有单向同步功能&#xff0c;使目录完全相同&#xff0c;它具有加密、缓存和联合后端&#xff0c;支持 Fuse 安装&#…

MindSpore是一种适用于端边云场景的新型开源深度学习训练/推理框架

MindSpore是一种适用于端边云场景的新型开源深度学习训练/推理框架。 MindSpore提供了友好的设计和高效的执行&#xff0c;旨在提升数据科学家和算法工程师的开发体验&#xff0c;并为Ascend AI处理器提供原生支持&#xff0c;以及软硬件协同优化。 同时&#xff0c;MindSpore…

【计算机网络】

1、应用层 web应用——http协议 请求消息格式&#xff1a;请求行&#xff0c;头部行&#xff0c;消息体 请求方法get&#xff0c;post&#xff0c;delete&#xff0c;put上传文件 Email应用——SMTP&#xff0c;POP3/IMAP DNS应用——DNS协议 P2P应用&#xff1a;文件分发等…

实战项目【7】MEMS惯性传感器的精度参数和单位换算

1 前言 有不少朋友在做项目的时候经常涉及到加速度计和陀螺仪的原始数据转换为其他的单位的问题&#xff0c;这篇文章梳理和推导一下。 1&#xff09;加速度计的原始数据 在应用时常见的转换单位有: g、m/s^2 、角度 2&#xff09;陀螺仪的原始数据 在应用时常见的转换单位有&a…

〖全域运营实战白宝书 - 运营角色认知篇⑤〗- “运营“ 是否有前途?

大家好&#xff0c;我是 哈士奇 &#xff0c;一位工作了十年的"技术混子"&#xff0c; 致力于为开发者赋能的UP主, 目前正在运营着 TFS_CLUB社区。 &#x1f4ac; 人生格言&#xff1a;优于别人,并不高贵,真正的高贵应该是优于过去的自己。&#x1f4ac; &#x1f4e…