当前位置: 首页 > 面试题库 >

在Java中使用apache事件模型解析Excel文件时,如何检查字符串中包含日期和指数的数字

唐康安
2023-03-14
问题内容

我正在解析一个excel文件,其中包含许多日期,例如13-4-2021和一些数字,采用这种3,7%,2,65%格式。所以我正在解析该excel文件,并且我将数据以字符串形式写入他们在一个文本文件中。所以我的问题是我得到的日期像44299这样的整数,而在Excel工作表中它实际上是04/13/2021格式。另一种情况是我有一些数字,例如3,7%,2,65%就像3.6999999999999998E-2一样,因此我可以使用

SimpleDateFormat("MM/dd/yyyy").format(javaDate)

这是我正在使用的代码

private static class SheetHandler extends DefaultHandler {
    private SharedStringsTable sst;
    private String lastContents;
    private boolean nextIsString;
    private int rowNumber;

    private SheetHandler(SharedStringsTable sst) {
        this.sst = sst;
    }

    public void startElement(String uri, String localName, String name,
            Attributes attributes) throws SAXException {
        try {

            // row => row
            if(name.equals("row")) {
                   if (attributes.getValue("r") != null) {
                    rowNumber = Integer.valueOf(attributes.getValue("r"));
                   } else {
                    rowNumber++;
                   }
                   //System.out.println("row: " + rowNumber);
                  }

        if (rowNumber > 6) {

        // c => cell
        if(name.equals("c")) {
            // Print the cell reference

            //System.out.print(attributes.getValue("r") + " - ");
            // Figure out if the value is an index in the SST
            String cellType = attributes.getValue("t");
            if(cellType != null && cellType.equals("s")) {
                nextIsString = true; 
            } else {
                nextIsString = false;
              }

        }
        // Clear contents cache
        lastContents = "";
        }
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    public void endElement(String uri, String localName, String name)
            throws SAXException {
        // Process the last contents as required.
        // Do now, as characters() may be called more than once

        if (rowNumber > 6) {


        if(nextIsString) {
            int idx = Integer.parseInt(lastContents);

            lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
            nextIsString = false;
        }
        // v => contents of a cell
        // Output after we've seen the string contents
        if(name.equals("v")) {
           // System.out.println(lastContents);

            if(!lastContents.isEmpty() ) // Here i am putting the values to a list to process

                pickUpExcelValues.add(lastContents);
            }
        }
    }

    public void characters(char[] ch, int start, int length)
            throws SAXException {
        lastContents += new String(ch, start, length);
    }
}

但是我将如何检查包含的字符串,让我们说44299是一个日期?而且我也不知道如何在写入文本文件时将该3.6999999999999998E-2转换为3.7%。如果有人有任何想法请帮助。


问题答案:

这个问题需要进一步的解释。

首先,它与如何使用已回答的apache事件用户模型跳过xlsm文件中的行有关。

但是,如果要使用XSSF和SAX(事件API)中的示例,则需要有关XMLOffice Open XML中使用的示例的基本知识。

ExampleEventUserModel是一个非常低级的示例,显示了流式传输原理。为了将其扩展为考虑格式,还需要解析样式表,然后使用DataFormatter。

下面是一个完整的示例,它正是在执行此操作。但是有一个更完整的示例,包括支持获取数字格式信息并将其应用于数字单元格(例如,格式化日期或百分比)。请参阅svn中的XLSX2CSV示例。

import java.io.InputStream;
import java.util.Iterator;

import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.BuiltinFormats;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.util.SAXHelper;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;


public class ExampleEventUserModel {
 public void processOneSheet(String filename) throws Exception {
  OPCPackage pkg = OPCPackage.open(filename);
  XSSFReader r = new XSSFReader( pkg );
  SharedStringsTable sst = r.getSharedStringsTable();

  StylesTable st = r.getStylesTable();
  XMLReader parser = fetchSheetParser(sst, st);

  // To look up the Sheet Name / Sheet Order / rID,
  //  you need to process the core Workbook stream.
  // Normally it's of the form rId# or rSheet#
  InputStream sheet2 = r.getSheet("rId2");
  InputSource sheetSource = new InputSource(sheet2);
  parser.parse(sheetSource);
  sheet2.close();
 }

 public void processAllSheets(String filename) throws Exception {
  OPCPackage pkg = OPCPackage.open(filename);
  XSSFReader r = new XSSFReader( pkg );
  SharedStringsTable sst = r.getSharedStringsTable();

  StylesTable st = r.getStylesTable();
  XMLReader parser = fetchSheetParser(sst, st);

  Iterator<InputStream> sheets = r.getSheetsData();
  while(sheets.hasNext()) {
   System.out.println("Processing new sheet:\n");
   InputStream sheet = sheets.next();
   InputSource sheetSource = new InputSource(sheet);
   parser.parse(sheetSource);
   sheet.close();
   System.out.println("");
  }
 }

 public XMLReader fetchSheetParser(SharedStringsTable sst, StylesTable st) throws SAXException, ParserConfigurationException {
/*
  XMLReader parser =
  XMLReaderFactory.createXMLReader(
       "org.apache.xerces.parsers.SAXParser"
  );
*/
  XMLReader parser = SAXHelper.newXMLReader();
  ContentHandler handler = new SheetHandler(sst, st);
  parser.setContentHandler(handler);
  return parser;
 }


 /** 
  * See org.xml.sax.helpers.DefaultHandler javadocs 
  */
 private static class SheetHandler extends DefaultHandler {
  private SharedStringsTable sst;
  private StylesTable st;
  private String lastContents;
  private boolean nextIsString;
  private boolean nextIsStyledNumeric;
  private boolean inlineStr;
  private int styleIndex;
  private DataFormatter formatter;

  private int rowNumber;

  private SheetHandler(SharedStringsTable sst, StylesTable st) {
   this.sst = sst;
   this.st = st;
   this.rowNumber = 0;
   this.formatter = new DataFormatter(java.util.Locale.US, true);
   this.styleIndex = 0;
  }

  public void startElement(String uri, String localName, String name,
            Attributes attributes) throws SAXException {

   // row => row
   if(name.equals("row")) {
    if (attributes.getValue("r") != null) {
     rowNumber = Integer.valueOf(attributes.getValue("r"));
    } else {
     rowNumber++;
    }
    System.out.println("row: " + rowNumber);
   }

   if (rowNumber > 6) {

    // c => cell
    if(name.equals("c")) {
     // Print the cell reference
     System.out.print(attributes.getValue("r") + " - ");

     String cellType = attributes.getValue("t");

     // Figure out if the value is an index in the SST
     nextIsString = false;
     if(cellType != null && cellType.equals("s")) {
      nextIsString = true;
     }

     // Figure out if the value is an inline string     
     inlineStr = false;
     if(cellType != null && cellType.equals("inlineStr")) {
      inlineStr = true;
     }

     // Figure out if the value is an styled numeric value or date
     nextIsStyledNumeric = false;
     if(cellType != null && cellType.equals("n") || cellType == null) {
      String cellStyle = attributes.getValue("s");
      if (cellStyle != null) {
       styleIndex = Integer.parseInt(cellStyle);
       nextIsStyledNumeric = true;
      }
     } 
    }
   }

   // Clear contents cache
   lastContents = "";
  }

  public void endElement(String uri, String localName, String name)
            throws SAXException {
   if (rowNumber > 6) {

    // Process the last contents as required.
    // Do now, as characters() may be called more than once

    // If the value is in the shared string table, get it
    if(nextIsString) {
     int idx = Integer.parseInt(lastContents);
     lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
     nextIsString = false;
    }

    // v => contents of a cell
    // Output after we've seen the string contents
    if(name.equals("v") || (inlineStr && name.equals("c"))) {
     // If the value is styled numeric, use DataFormatter to formaat it
     if (nextIsStyledNumeric) {
      XSSFCellStyle style = st.getStyleAt(styleIndex);
      int formatIndex = style.getDataFormat();
      String formatString = style.getDataFormatString();
      if (formatString == null) {
       // formatString could not be found, so it must be a builtin format.
       formatString = BuiltinFormats.getBuiltinFormat(formatIndex);
      }
      double value = Double.valueOf(lastContents);
      lastContents = formatter.formatRawCellContents(value, formatIndex, formatString);
      nextIsStyledNumeric = false;
     } 
     // Print out the contents
     System.out.println(lastContents);
    }
   }
  }

  public void characters(char[] ch, int start, int length)
            throws SAXException {
   //collect each character part to the content
   lastContents += new String(ch, start, length);
  }
 }

 public static void main(String[] args) throws Exception {
  ExampleEventUserModel example = new ExampleEventUserModel();
  //example.processOneSheet(args[0]);
  example.processAllSheets(args[0]);
 }
}


 类似资料:
  • 问题内容: 如何检查字符串是否包含以下格式的日期: 2012年1月15日,星期日,美国东部标准时间晚上7:36 我正在使用的数据包含大量字符串。但是我要查找的字符串类型包含一个2或3个单词名称和一个日期。我正在检查日期以识别这些类型的字符串。 我已经找到了这种日期的simpleDateFormat。 但是我不知道如何进一步进行。 我猜测正则表达式可能有效,但是当月/日名称的长度不同时,我不知道如何

  • 问题内容: 在Java forString类中,有一个称为matchs的方法,该方法如何使用正则表达式检查我的字符串是否只有数字。我尝试了以下示例,但它们均使我返回了false。 问题答案: 尝试 要么 按照Java 正则表达式 ,其 含义是“一次或多次”,并且其含义是“数字”。 注意:“双反斜杠”是一个 转义序列, 用于获取单个反斜杠-因此,在Java字符串中会提供实际结果: 参考文献: Jav

  • 在Java for String类中有一个叫做matches的方法,如何使用这个方法使用正则表达式来检查我的字符串是否只有数字。我尝试了下面的例子,但他们都返回我的结果是假的。

  • 我需要读取一个非常大的Excel文件,该文件既有日期编号,也有非日期编号。我发现的所有示例似乎都能做到这一点或那一点(将单元格标识为日期值或在恒定内存中读取文件)。 对于非常大的文件,唯一有效的解决方案是此处所述的StreamingReader方法(此处所述的其他示例要么不适用于我的文件格式,要么出现内存不足堆错误)。 用java读取大型Excel文件(500K行) http://poi.apac

  • 大家好,我正在努力找出如何检查“我的edittext”值是否包含字母和数字,如果用户输入例如“JDF23D”告诉他们删除数字,我会显示一个snackbar,但我的错误是不管它保留在那里,否则你会建议什么?

  • 问题内容: 例如,当我拆分字符串时,我想检查一下我的第一部分是否仅包含数字和小数点。 我做了以下 但这仅检查数字而不是小数。如何在其中检查小数?例如,我想检查0.12.13.14是否可以正常工作,而像0.12.13.14x这样的东西将无法工作。 问题答案: 在正则表达式中添加点字符,如下所示: 该是允许多个数字/小数点。 在情况下,至少一个数字/小数点是必需的,代替具有用于一个或多个出现。 编辑: