【问题标题】:How to read an excel file contents on client side?如何在客户端读取excel文件内容?
【发布时间】:2011-09-16 23:25:25
【问题描述】:

从 JSP 页面,我需要浏览 excel 文件,在系统上选择文件后,我需要读取该 excel 文件内容并填写表格。

目前我已经尝试过使用下面的代码,但它只在 IE 中工作,对 ActiveXObject 的 IE 互联网选项进行了一些更改。它不适用于其他浏览器。

<script>
    function mytest2() {
        var Excel;
        Excel = new ActiveXObject("Excel.Application"); 
        Excel.Visible = false;
        form1.my_textarea2.value = Excel.Workbooks.Open("C:/Documents and Settings/isadmin/Desktop/test.xlsx").ActiveSheet.Cells(1,1).Value;
        Excel.Quit();
    }
</script>

请提出一些解决方案,使其适用于所有浏览器。

【问题讨论】:

    标签: javascript excel jsp


    【解决方案1】:

    通常不可能在浏览器中通过 JavaScript 读取/写入任何文件。因此,如果没有任何其他插件,您将无法从浏览器读取/写入 Excel 文件。 Excel 的 ActiveX 对象允许您这样做,但只有 IE 支持 ActiveX 对象。

    其他浏览器可能还有其他插件,但我不知道。

    首先,您为什么要这样做?能给个用例吗?也许有比您正在尝试的更好的选择。

    更新

    您必须将 excel 文件传递​​给服务器并在服务器端读取 excel(例如在 servlet 中)。

    您必须在 JSP 中的多部分表单中使用 &lt;input type='file'&gt;
    &lt;form name="myForm" action="myServlet" enctype="multipart/form-data" method="post"&gt;

    在服务器端,您可能希望使用Apache Commons File Upload

    一旦有了文件(或上面的流),您就可以使用 Apache POI HSSF/XSSF 解析文件,然后将数据更新到数据库或将其传回 JSP

    【讨论】:

    • 项目要求——用户必须从 jsp 页面选择他系统上的 eXcel 文件,然后自动填充所有表单字段。请建议我该怎么做?
    • “通常不可能在浏览器中通过 JavaScript 读取/写入任何文件。” 所以这是可能的,但插件是您最好的选择吗?但是您可以做任何您喜欢的事情,并且不会被使用该服务来做肮脏的工作?尽管 xlsx.js 确实通过糟糕的 DX 实现了它,但它可以通过大量研究来完成。我见过很多例子。
    • 示例完全在浏览器中完成,速度快如闪电。我正在考虑重写他们的示例代码。里面很糟糕。 oss.sheetjs.com/js-xlsx
    【解决方案2】:

    我一直这样做 - 我的原型旨在让利益相关者修改 Excel 并让它填充 html 原型,通常不需要服务器。

    1. 将 Excel 保存为 XML
    2. 通过 AJAX 加载 XML 并解析出结构

    (1) 这是我在我的 excel 文件中放入的一个方便的按钮宏,可以轻松保存为 XML(并重新保存为 xls):

        Sub SaveAndExportXML()
          Dim fname As String
          Dim fnamexml As String
          fname = ThisWorkbook.FullName
          fnamexml = Replace(fname, ".xls", ".xml", 1, 1, vbTextCompare)
    
          If MsgBox("Will save the following (runtime XML and source XLS) files: " & vbNewLine & "XML: " & fnamexml & vbNewLine & "Src: " & fname & vbNewLine & vbNewLine & "Ok?  If so, please click Yes here and on the next 3 prompts...", vbYesNo) = vbNo Then Exit Sub
          ActiveWorkbook.SaveAs Filename:=fnamexml, FileFormat:=xlXMLSpreadsheet, ReadOnlyRecommended:=False, CreateBackup:=False
          're-save as xls:
          ActiveWorkbook.SaveAs Filename:=fname, FileFormat:=xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False, CreateBackup:=False
        End Sub
    

    (2) 解析JS比较复杂,但前提很简单。将有 XML 对象,如 Worksheet、Table、Row、Cell 和 Data。还有一个名为 ss:Index 的 XML 属性有时我觉得很方便。

    【讨论】:

      【解决方案3】:

      xlsx 电子表格是一个 zip 文件,其中包含一堆 xml 文件。使用 zip.js 之类的东西,您可以提取 xml 文件并在浏览器中解析它们。 xlsx.js 这样做。 Here's my simple example。为方便起见,复制到这里:

      /*
          Relies on jQuery, underscore.js, Async.js (https://github.com/caolan/async), and zip.js (http://gildas-lormeau.github.com/zip.js).
          Tested only in Chrome on OS X.
      
          Call xlsxParser.parse(file) where file is an instance of File. For example (untested):
      
          document.ondrop = function(e) {
              var file = e.dataTransfer.files[0];
              excelParser.parse(file).then(function(data) {
                  console.log(data);
              }, function(err) {
                  console.log('error', err);
              });
          }
      */
      
      xlsxParser = (function() {
          function extractFiles(file) {
              var deferred = $.Deferred();
      
              zip.createReader(new zip.BlobReader(file), function(reader) {
                  reader.getEntries(function(entries) {
                      async.reduce(entries, {}, function(memo, entry, done) {
                          var files = ['xl/worksheets/sheet1.xml', 'xl/sharedStrings.xml'];
                          if (files.indexOf(entry.filename) == -1) return done(null, memo);
      
                          entry.getData(new zip.TextWriter(), function(data) {
                              memo[entry.filename.split('/').pop()] = data;
                              done(null, memo);
                          });
                      }, function(err, files) {
                          if (err) deferred.reject(err);
                          else deferred.resolve(files);
                      });
                  });
              }, function(error) { deferred.reject(error); });
      
              return deferred.promise();
          }
      
          function extractData(files) {
              var sheet = $(files['sheet1.xml']),
                  strings = $(files['sharedStrings.xml']),
                  data = [];
      
              var colToInt = function(col) {
                  var letters = ["", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
                  var col = $.trim(col).split('');
      
                  var n = 0;
      
                  for (var i = 0; i < col.length; i++) {
                      n *= 26;
                      n += letters.indexOf(col[i]);
                  }
      
                  return n;
              };
      
              var Cell = function(cell) {
                  cell = cell.split(/([0-9]+)/);
                  this.row = parseInt(cell[1]);
                  this.column = colToInt(cell[0]);
              };
      
              var d = sheet.find('dimension').attr('ref').split(':');
              d = _.map(d, function(v) { return new Cell(v); });
      
              var cols = d[1].column - d[0].column + 1,
                  rows = d[1].row - d[0].row + 1;
      
              _(rows).times(function() {
                  var _row = [];
                  _(cols).times(function() { _row.push(''); });
                  data.push(_row);
              });
      
              sheet.find('sheetData row c').each(function(i, c) {
                  var $cell = $(c),
                      cell = new Cell($cell.attr('r')),
                      type = $cell.attr('t'),
                      value = $cell.find('v').text();
      
                  if (type == 's') value = strings.find('si t').eq(parseInt(value)).text();
      
                  data[cell.row - d[0].row][cell.column - d[0].column] = value;
              });
      
              return data;
          }
      
          return {
              parse: function(file) {
                  return extractFiles(file).pipe(function(files) {
                      return extractData(files);
                  });
              }
          }
      })();
      

      【讨论】:

        【解决方案4】:

        您可以使用HTML5 File APImost modern browsers 中加载和打开文件客户端

        加载文件后,您可以使用支持某些 excel 输出格式(例如 csv / xlsx)的库来解析内容。

        这里有几个选项...

        【讨论】:

          【解决方案5】:

          这个适用于所有主流浏览器。

          https://catamphetamine.github.io/read-excel-file/

          <input type="file" id="input" />
          
          import readXlsxFile from 'read-excel-file'
          
          const input = document.getElementById('input')
          
          input.addEventListener('change', () => {
            readXlsxFile(input.files[0]).then((data) => {
              // `data` is an array of rows
              // each row being an array of cells.
            })
          })
          

          在上面的示例中,data 是原始字符串数据。 通过传递 schema 参数,可以将其解析为具有严格模式的 JSON。有关示例,请参阅 API 文档。

          API 文档: http://npmjs.com/package/read-excel-file

          【讨论】:

            猜你喜欢
            • 2021-03-20
            • 1970-01-01
            • 1970-01-01
            • 2016-02-03
            • 2012-01-23
            • 2019-06-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多