JSP 如何在客户端读取excel文件内容?

brtdzjyr  于 2022-12-07  发布在  其他
关注(0)|答案(6)|浏览(260)

从JSP页面,我需要浏览excel文件,并在系统上选择文件后,我需要读取该excel文件的内容,并填写我的表单。
目前我已经尝试与下面的代码,但它只工作在IE与一些变化的IE互联网选项的ActiveXObject。它不工作在其余的浏览器。

<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>

请建议一些解决方案,使其在所有浏览器中工作。

zhte4eai

zhte4eai1#

一个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);
            });
        }
    }
})();
np8igboo

np8igboo2#

您可以使用HTML5 File API
加载文件后,您可以使用支持某些Excel输出格式(如csv / xlsx)的库解析内容。
这里有几个选项...

46qrfjad

46qrfjad3#

在浏览器中通过JavaScript读/写任何文件通常是不可能的。因此,如果没有任何附加的插件,您将无法从浏览器中读/写Excel文件。Excel的ActiveX对象允许您这样做,但只有IE支持ActiveX对象。
可能有其他插件为其他浏览器,但我知道没有。
首先,你为什么要这样做?你能给予一个用例吗?也许有比你正在尝试的更好的选择。

更新

您必须将excel文件传递到服务器,并在服务器端阅读excel(例如在servlet中)。
您必须在多部分表单的JSP中使用<input type='file'>
<form name="myForm" action="myServlet" enctype="multipart/form-data" method="post">
在服务器端,您可能希望使用Apache Commons File Upload
一旦有了文件(或其中的流),就可以使用Apache POI HSSF/XSSF解析文件,然后将数据更新到数据库或将其传递回JSP

tjrkku2a

tjrkku2a4#

我一直都在这样做--我的原型被设计成让涉众修改一个excel,并让它填充html原型,通常不需要服务器。
1.将Excel另保存为XML
1.通过 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的解析比较复杂,但前提很简单。其中有Worksheet、Table、Row、Cell和Data等XML对象。还有一个XML属性ss:Index,有时候我觉得很方便。

ct2axkht

ct2axkht5#

这个可以在所有主流浏览器中使用。
https://catamphetamine.github.io/read-excel-file/
第一个
在上面的示例中,data是原始字符串数据。通过传递schema参数,可以将其解析为具有严格模式的JSON。有关示例,请参阅API文档。
API文档:http://npmjs.com/package/read-excel-file

lyr7nygr

lyr7nygr6#

使用SheetJS和ECMAScript可以执行以下操作:
在文件中添加以下内容:

import { read, writeFileXLSX, utils } from "https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs";
        
// returns the content of the File passed as argument as a binary string
async function readFileAsBinaryString(file) { /* use in an async function to await on the result */
            
      const binaryString = await new Promise((resolve, reject) => {
                const reader = new FileReader();
                reader.onload = () => resolve(reader.result);
                reader.onerror = () => reject('error : cannot read the file');
                reader.readAsBinaryString(file);
      });
        
      //console.log(binaryString);
      return binaryString;
}
        
// returns the content of the Excel File passed as argument as a CSV formatted text
async function ExcelFileToCSV(file) {
      try {
              const data = await readFileAsBinaryString(file);
                
              let workbook = read(data, {
                  type:'binary',
              });
        
              let sheets = workbook.Sheets; // the sheets presents in the file
              let length = Object.keys(sheets).length; // number of sheets in the file
        
              if (length == 1) { // if there's only one sheet in the file
                  return utils.sheet_to_csv(sheets.sheet1); // returns the sheet converted to csv !! NOT AN ARRAY !!
                
              } else if (length > 1) { // else if there are more than one sheet in the file
                  let returnVal = [];
        
                  for (let key in sheets) { // loop over the sheets
                      returnVal.push(utils.sheet_to_csv(sheets[key])); // adds the current sheet converted to csv in the returnVal array 
                  }
                  //console.log(returnVal);
                  return returnVal; // returns an array of csv converted sheets !! ARRAY !!
              }
        
          } catch (err) {
                console.log(err);
          }
}

也可以将其保存在另一个文件中。
如果这样做,您将需要导出将要使用的函数,并将其导入到要使用它的文件中。
使用方法:

async function readFile(file) { // single file
         let fileContent = await ExcelFileToCSV(file);
         console.log(fileContent); // log the file content
         // do stuff with fileContent here
}

如果文件中只有一个sheet,则fileContent将包含字符串,否则它将是stringarray,每个string与用于调用的文件的一个sheet匹配。

async function readFile(files) { // multiple files
             let length = files.length;
             let filesContents = [];

             for (var i=0; i<length; i++) {
                     let fc = await ExcelFileToCSV(files[i]);
                     filesContents.push(fc);
             }
                   
             console.log(filesContents); // log  filesContents
             // do stuff with filesContents here
    }

这样做的好处是可以用“同步方式”处理异步代码。
如果您对检索其他格式的文件内容感兴趣,您可以检查utils.sheet_to_XXX信息here,并替换ExcelFileToCSV()中的utils.sheet_to_csv指令,或者最好在另一个相应命名的函数中进行。
如果你想在一个html页面中使用函数,你需要在这些scripts标签中进行:<script type="module" defer></script>

相关问题