如何使用POI读取xlsx文件?

huangapple go评论75阅读模式
英文:

How to read xlsx file using POI?

问题

import groovy.sql.Sql
import org.apache.poi.xssf.usermodel.XSSFCell
import javax.xml.soap.Text
import java.sql.Blob
import java.sql.Connection
import java.sql.DriverManager
import org.apache.poi.ss.usermodel.*
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import java.util.Iterator;
import java.io.*

class XM_PARSE_XLS {

    def execute(Connection conn, InputStream p_file, String p_filename) {

        Sql sql = new Sql(conn)

        XSSFWorkbook wb = new XSSFWorkbook(p_file);

        ArrayList<HashMap<String, String>> arrAllData = new ArrayList<HashMap<String, String>>();
        String strsql
        Integer cntStr = 0
        HashSet rw_okpo = new HashSet();

        wb.each { XSSFSheet myExcelSheet ->
            DataFormatter formatter = new DataFormatter(Locale.ROOT);

            myExcelSheet.each { Row myrow ->
                HashMap<String, String> hm = new HashMap<String, String>();

                if (cntStr >= 0) {
                    Integer numCell = 0;
                    String typ = '';

                    myrow.each { Cell mycell ->
                        String value = "";
                        if (mycell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
                            value = mycell.getStringCellValue();
                            typ = 'S';
                        } else {
                            value = formatter.formatCellValue(mycell);
                            value = value.replace(',', '');
                            typ = 'N';
                            if (cntStr >= 0) {
                                switch (numCell) {
                                    case 0:
                                        hm.put("t0", value + ";");
                                        break;
                                    case 1:
                                        hm.put("t1", value + ";");
                                        break;
                                    // ... (cases for other columns)
                                    case 17:
                                        hm.put("t17", value + "\r\n");
                                        break;
                                }
                                numCell = numCell + 1;
                            }
                        }
                    }
                }
                if (hm) arrAllData.add(hm);
                cntStr = cntStr + 1;
            }
        }
        return res;
    }

    static void main(String... args) {
        Class.forName("oracle.jdbc.driver.OracleDriver")
        connection.setAutoCommit(true)

        try {
            def file = new File("test.xlsx").newInputStream()
            def SSC = new XM_PARSE_XLS()
            def res = SSC.execute(connection, file, "test.xlsx")
        } finally {
            connection.close()
        }
    }
}

Please note that the provided code is a Groovy script for reading data from an XLSX file using Apache POI. The script seems to have some issues, such as referencing res and connection variables that are not defined in the provided code snippet. Additionally, the code contains some commented-out lines, and the handling of different columns in the switch statement is cut off. You might need to review and adjust the code accordingly for your specific use case.

英文:

I read the xls file using POI HSSF, everything was correct. But I didn't learn how to read the input file xlsx. Previously, I did not work with xlsx, I read the material on the network on different resources, I did not notice the difference except for replacing HSSF with XSSF and connecting additional. libraries. However, it throws an error:

> Exception in thread "main" java.lang.NoSuchMethodError:
> org.apache.poi.util.XMLHelper.newDocumentBuilder () Ljavax / xml /
> parsers / DocumentBuilder;

Swears at

XSSFWorkbook wb = new XSSFWorkbook (p_file);
def res = SSC.execute (connection, file, &quot;test.xlsx&quot;)

The code is given below (I will be very grateful if anyone can help in solving the problem now / on ";" do not pay attention, because I use groovy, the rest is similar to java):

import groovy.sql.Sql
import org.apache.poi.xssf.usermodel.XSSFCell
import javax.xml.soap.Text
import java.sql.Blob
import java.sql.Connection
import java.sql.DriverManager
import org.apache.poi.ss.usermodel.*
import org.apache.poi.hssf.usermodel.*
import org.apache.poi.xssf.usermodel.XSSFWorkbook; //New imports to read XLSX format
import org.apache.poi.xssf.usermodel.XSSFSheet; //New imports to read XLSX format
import org.apache.poi.ss.usermodel.*;
import java.util.Iterator;
import java.io.*;
class XM_PARSE_XLS {
def execute(Connection conn, InputStream p_file, String p_filename) {
Sql sql = new Sql(conn)
XSSFWorkbook wb = new XSSFWorkbook(p_file);
ArrayList&lt;HashMap&lt;String, String&gt;&gt; arrAllData = new ArrayList&lt;HashMap&lt;String, String&gt;&gt;();
String strsql
Integer cntStr = 0
HashSet rw_okpo = new HashSet();
// идем по листам в файле
wb.each { XSSFSheet myExcelSheet -&gt;
DataFormatter formatter = new DataFormatter(Locale.ROOT);
// идем по страницам файла
myExcelSheet.each{  Row myrow -&gt;
HashMap&lt;String, String&gt; hm = new HashMap&lt;String, String&gt;();
if (cntStr &gt;= 0) {
// идем по строкам с данными
Integer numCell = 0;
String typ = &#39;&#39;;
myrow.each { Cell mycell -&gt;
String value = &quot;&quot;; // приводит любые ячейки к строковому формату
// если тип Строка
if (mycell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
value = mycell.getStringCellValue();
typ = &#39;S&#39;
// если тип число
}  else {
// а для числовых ячеек или ячеек даты значение будет отформатировано на основе правил форматирования / стиля, примененных к ячейке, а затем возвращено как строка
value = formatter.formatCellValue(mycell);
value = value.replace(&#39;,&#39;,&#39;&#39;);
typ = &#39;N&#39;
if (cntStr &gt;= 0){
switch(numCell) { //0-17
case 0:
hm.put(&quot;t0&quot;, value + &quot;;&quot;);
break;
case 1:
hm.put(&quot;t1&quot;, value + &quot;;&quot;);
break;
case 2:
hm.put(&quot;t2&quot;, value + &quot;;&quot;);
break;
case 3:
hm.put(&quot;t3&quot;, value + &quot;;&quot;);
break;
case 4:
hm.put(&quot;t4&quot;, value + &quot;;&quot;);
break;
case 5:
hm.put(&quot;t5&quot;, value + &quot;;&quot;);
break;
case 6:
hm.put(&quot;t6&quot;, value + &quot;;&quot;);
break;
case 7:
hm.put(&quot;t7&quot;, value + &quot;;&quot;);
break;
case 8:
hm.put(&quot;t8&quot;, value + &quot;;&quot;);
break;
case 9:
hm.put(&quot;t9&quot;, value + &quot;;&quot;);
break;
case 10:
hm.put(&quot;t10&quot;, value + &quot;;&quot;);
break;
case 11:
hm.put(&quot;t11&quot;, value + &quot;;&quot;);
break;
case 12:
hm.put(&quot;t12&quot;, value + &quot;;&quot;);
break;
case 13:
hm.put(&quot;t13&quot;, value + &quot;;&quot;);
break;
case 14:
hm.put(&quot;t14&quot;, value + &quot;;&quot;);
break;
case 15:
hm.put(&quot;t15&quot;, value + &quot;;&quot;);
break;
case 16:
hm.put(&quot;t16&quot;, value + &quot;;&quot;);
break;
case 17:
hm.put(&quot;t17&quot;, value + &quot;\r\n&quot;);
break;
}
numCell = numCell + 1;
}
}
}
if(hm) arrAllData.add(hm);
cntStr = cntStr + 1;
}
}
return res;
}
static void main(String... args) {
Class.forName(&quot;oracle.jdbc.driver.OracleDriver&quot;)
//Connection connection = DriverManager.getConnection(&quot;jdbc:oracle:thin:@10.193.21.75:3333/OLAP2&quot;, &quot;LAS&quot;, &quot;ASfDER7F4FA&quot;)
connection.setAutoCommit(true)
try {
def file = new File(&quot;test.xlsx&quot;).newInputStream()
def SSC = new XM_PARSE_XLS()
def res = SSC.execute(connection,file,&quot;test.xlsx&quot;)
} finally {
connection.close()
}
}
}

答案1

得分: 3

在运行时发生NoSuchMethodError错误,如果代码运行时使用的库版本与其编译时使用的版本不同。

在这里,代码可能是使用apache poi 4.1.2编译的,但在运行时使用了较低版本的apache poi

方法public static DocumentBuilder newDocumentBuilder()是在apache poi 4.1.2中引入的,位于org.apache.poi.util.XMLHelper中。在较低版本中不存在。

还要确保不要混用不同版本的apache poi。这不受支持,可能会导致此类错误,因为不同版本会导出不同版本的方法。参见faq-N10204

也许apache poi 的较低版本类也来自其他库。您可以在运行时询问ClassLoader一个特定类(在您的情况下是org.apache.poi.util.XMLHelper)来自哪里:

...
ClassLoader classloader = org.apache.poi.util.XMLHelper.class.getClassLoader();
java.net.URL res = classloader.getResource("org/apache/poi/util/XMLHelper.class");
String path = res.getPath();
System.out.println("XMLHelper来自于" + path);
...

如果这不是您所期望的jar,您至少会知道哪个其他库也提供了该类。

英文:

A NoSuchMethodError on run time occurs if the code runs using another library version than it was compiled with.

Here the code probably was compiled using apache poi 4.1.2 but on run time there is a lower version of apache poi used.

The method public static DocumentBuilder newDocumentBuilder() was introduced in org.apache.poi.util.XMLHelper in apache poi 4.1.2. It is not present in lower versions.

Also make sure you are not mixing different apache poi versions. That is not supported and also might lead to such errors because different versions exporting different versions of methods too. See faq-N10204.

Maybe lower versions of apache poi classes are shipped from other libraries too. You can ask the ClassLoader where a special class (org.apache.poi.util.XMLHelper in your case) came from on run time:

...
ClassLoader classloader = org.apache.poi.util.XMLHelper.class.getClassLoader();
java.net.URL res = classloader.getResource(&quot;org/apache/poi/util/XMLHelper.class&quot;);
String path = res.getPath();
System.out.println(&quot;XMLHelper came from &quot; + path);
...

If that is not the jar you expect, you get at least an idea which other library ships that class too.

huangapple
  • 本文由 发表于 2020年9月4日 14:30:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/63735971.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定