本人属于一个实习菜鸟,大神请谨慎阅读............
在开发过程中,难免会碰到用前端来处理excel文件的需求,我们需要解析出excel文件的内容然后在以对象的形式展示或者与后端对接
文件选择 => FileReader对象得到二进制数据 => XLSX处理二进制数据 => 得到数据
首先我们需要的是一个导入的按钮但是我们导入按钮并不好处理触发选择文件(file)的change事件所以我们可以用定位来解决这个问题,原理就是:选择文件按钮(file)覆盖在正常按钮上面然后在把选择文件按钮(file)透明的变为0即可

<el-button size="mini" type="success" style="margin-top: 10px" :disabled="disabled"
class="el-dialog-position">
<span v-if="importStatus === false">
导入<i class="el-icon-upload el-icon--right" />
<input ref="files" type="file" v-if="!disabled" class="excelFile" @change="excelFileMethod" />
</span>
<span v-if="importStatus === true">
导入中<i class="el-icon-loading el-icon--right" />
</span>
</el-button>
接下来就是chnage事件了,当用户更改 input、select 和textarea元素的值时,change 事件在这些元素上触发。和 input 事件不同的是,并不是每次元素的 value 改变时都会触发 change 事件。我们选择文件并确认以后得到了下面着一些大堆数据
这一大堆的数据我们不用管,我们只关注target对象里面的files对象就可以了因为等一下我们需要用到,但是注意这里的只是文件的信息并不是数据更不是二进制文件!!!!!!

先对fileReader做个介绍,FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。(官网原文)这里给你们个地址自己去看属性和方法的使用我就不做过多的介绍了.........先看代码:
// change事件
excelFileMethod(e) {
var _this = this
// excel文件信息
const files = e.target.files
console.log(files);
// 构建fileReader对象
const fileReader = new FileReader()
// 读取操作完成时
fileReader.onload = function(e) {
try {
// 二进制数据
console.log(e.target.result)
} catch (e) {
console.log('文件类型不正确')
return
}
}
// 读取指定文件内容
fileReader.readAsBinaryString(files[0])
}
- 第一步我们需要构建一个新的FileReader对象
- 第二步使用FileReader.readAsBinaryString()读取指定的Blob中的内容。一旦完成,
result属性中将包含所读取文件的原始二进制数据。- 第三步就是FileReader.onLoad该事件在读取操作完成时触发。
XLSX插件的使用,使用前我们需要下载并CND使用也可以是npm安装看个人需求,我这里是vue项目所以就是npm安装了然后还需要我们引入XLSX,方法如下:
import XLSX from 'xlsx'
通过上面的代码我们已经得到了二进制数据了,我们就开始对二进制数据进行解析吧!使用XLSX.read(data, { type: type})方法来实现,type主要取值如下:
- base64:以base64方式读取
- binary:BinaryString格式( byte n is data.charCodeAt(n) )
- string:UTF8编码的字符串
- buffer:nodejs Buffer
- array:Uint8Array,8位无符号数组
- file:文件的路径(仅nodejs下支持)
这个方法返回一个workBook对象,对象的内容如下:

可以看到workBook对象,sheetNames里面保存了所有的sheet名字,然后Sheets则保存了每个sheet的具体内容(我们称之为Sheet Object)。每一个sheet是通过类似A1这样的键值保存每个单元格的内容,我们称之为单元格对象(Cell Object)
- XLSX.utils.sheet_to_csv:生成CSV格式
- XLSX.utils.sheet_to_txt:生成纯文本格式
- XLSX.utils.sheet_to_html:生成HTML格式
- XLSX.utils.sheet_to_json:输出JSON格式
这里用到的是XLSX.utils.sheet_to_json所以我着重介绍,XLSX.utils.sheet_to_json(data, type)有两个参数,第一个是我们wordBook对象里面Sheets对象对应的数据,第二个参数配置如下:
- raw: 使用原始值 (true) 或格式化字符串 (false) (默认值:true)
- dateNF: 在字符串输出中使用指定的日期格式(默认值:FMT 14)
- defval: 使用指定值代替 null 或 undefined ()
- blankrows: 在输出中包含空行**(默认值:** )
range:
(number)使用工作表范围,但将起始行设置为值
(String)使用指定范围(A1 样式的有界范围字符串
(default)使用工作表范围 ( worksheet[‘!ref’])
header:
1: 生成数组数组(“二维数组”)
"A".行对象键是文字列标签
array of strings: 使用指定的字符串作为行对象中的键
(default): 将第一行作为键读取并消除歧义
下面就是整个导入excel文件并读取数据的代码流程了,我们可以对得到的数据作为参数与后端接口进行对接就可以了!
// 处理excel文件
excelFileMethod(e) {
// 导入状态和文件信息
var _this = this
_this.importStatus = true
const excelFile = e.target.files
// 构建fileReader对象
const fileReader = new FileReader()
// 该事件为读取完成时触发
fileReader.onload = function (ev) {
try {
const data = ev.target.result
const workbook = XLSX.read(data, {type: 'binary'})
const list = ''
const listNew = list.concat(XLSX.utils.sheet_to_json(workbook.Sheets['sheets1'], {header: 1}))
_this.excelData.list = listNew.slice(6).split(',')
// 得到的数据发送axios请求
importExcel(_this.excelData).then(res => {
console.log(res)
_this.importStatus = false
if (res.code === 200) {
_this.$alert(res.data.msg, '导入成功', {
confirmButtonText: '确定',
callback: () => {
// 确认后做什么
}
})
} else {
_this.$alert(res.data.msg, '导入失败', {
confirmButtonText: '确定',
callback: () => {
// 确认后做什么
}
})
}
})
} catch (e) {
_this.$message({message: '文件类型不正确', type: 'warning'})
}
}
// 读取数据
fileReader.readAsBinaryString(excelFile[0])
}
后续还会持续更新技术问题感兴趣的小伙伴可以点关注或者是私信我哦!!!
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题