有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何创建并写入Excel文件(.xlsx)?

Java开发人员可以使用很多在Android上无法使用的方法

我开始使用像OpenCSV这样的库,但不幸的是Excel已经known issues打开了CSV文件

然后我试着用:

  • ApachePOI——它的方法肯定太多了
  • JExcelAPI——它可以工作,但只在旧的二进制文件上工作。xls文件
  • docx4j——还是太多JAR了,因为它基于JAXB,而Android中不包括JAXB

我的问题是,如何在中创建一个简单的Excel文件。Android上的xlsx格式,不超过65k方法


共 (5) 个答案

  1. # 1 楼答案

    因为这个问题似乎相当简单:“为Excel(*.xlsx)创建Office Open XML文件的最轻量级方法是什么?”,我将提供一个不需要任何库的示例,除了默认的java.langjava.iojava.util.zip

    *.xlsx文件只不过是一个ZIP存档,包含XML文件和目录结构中的其他文件。因此,我们所需要的只是创建、读取和写入ZIP档案以及创建、读取和写入XML文件的可能性。对于ZIP部分,我使用java.util.zip,对于XML部分,我使用字符串操作。通过字符串操作创建和操作XML并不是最推荐的操作XML的方法,但它是最轻量级的方法,因为它不需要任何额外的XML库

    完整示例:

    import java.io.OutputStream;
    import java.io.ByteArrayOutputStream;
    
    import java.util.zip.*;
    
    public class CreateXLSXFromScratch {
    
     //some static parts of the XLSX file:
    
     static String content_types_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default ContentType=\"application/vnd.openxmlformats-package.relationships+xml\" Extension=\"rels\"/><Default ContentType=\"application/xml\" Extension=\"xml\"/><Override ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\" PartName=\"/docProps/app.xml\"/><Override ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\" PartName=\"/docProps/core.xml\"/><Override ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\" PartName=\"/xl/sharedStrings.xml\"/><Override ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\" PartName=\"/xl/styles.xml\"/><Override ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\" PartName=\"/xl/workbook.xml\"/><Override ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\" PartName=\"/xl/worksheets/sheet1.xml\"/></Types>";
    
     static String docProps_app_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"><Application>" + "Created Low level From Scratch" + "</Application></Properties>";
    
     static String docProps_core_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><dcterms:created xsi:type=\"dcterms:W3CDTF\">" + java.time.Instant.now().truncatedTo(java.time.temporal.ChronoUnit.SECONDS).toString() + "</dcterms:created><dc:creator>" + "Axel Richter from scratch" + "</dc:creator></cp:coreProperties>";
    
     static String _rels_rels_xml  = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Target=\"xl/workbook.xml\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\"/><Relationship Id=\"rId2\" Target=\"docProps/app.xml\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\"/><Relationship Id=\"rId3\" Target=\"docProps/core.xml\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\"/></Relationships>";
    
     static String xl_rels_workbook_xml_rels_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Target=\"sharedStrings.xml\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings\"/><Relationship Id=\"rId2\" Target=\"styles.xml\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\"/><Relationship Id=\"rId3\" Target=\"worksheets/sheet1.xml\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\"/></Relationships>";
    
     static String xl_sharedstrings_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><sst count=\"0\" uniqueCount=\"0\" xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"/>"; 
    
     static String xl_styles_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"><numFmts count=\"0\"/><fonts count=\"1\"><font><sz val=\"11.0\"/><color indexed=\"8\"/><name val=\"Calibri\"/><family val=\"2\"/><scheme val=\"minor\"/></font></fonts><fills count=\"2\"><fill><patternFill patternType=\"none\"/></fill><fill><patternFill patternType=\"darkGray\"/></fill></fills><borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs><cellXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/></cellXfs></styleSheet>";
    
     static String xl_workbook_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"><workbookPr date1904=\"false\"/><bookViews><workbookView activeTab=\"0\"/></bookViews><sheets><sheet name=\"" + "Sheet1" + "\" r:id=\"rId3\" sheetId=\"1\"/></sheets></workbook>";
    
     static String xl_worksheets_sheet1_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"><dimension ref=\"A1\"/><sheetViews><sheetView workbookViewId=\"0\" tabSelected=\"true\"/></sheetViews><sheetFormatPr defaultRowHeight=\"15.0\"/><sheetData/><pageMargins bottom=\"0.75\" footer=\"0.3\" header=\"0.3\" left=\"0.7\" right=\"0.7\" top=\"0.75\"/></worksheet>";
    
     public static void main(String[] args) throws Exception {
    
      // result goes into a ByteArrayOutputStream
      ByteArrayOutputStream resultout = new ByteArrayOutputStream();
    
      // needed objects
      ZipEntry zipentry = null;
      byte[] data = null;
    
      // create ZipOutputStream
      ZipOutputStream zipout = new ZipOutputStream(resultout);
    
      // create the static parts of the XLSX ZIP file:
    
      zipentry = new ZipEntry("[Content_Types].xml");
      zipout.putNextEntry(zipentry);
      data = content_types_xml.getBytes();
      zipout.write(data, 0, data.length);
      zipout.closeEntry();
    
      zipentry = new ZipEntry("docProps/app.xml");
      zipout.putNextEntry(zipentry);
      data = docProps_app_xml.getBytes();
      zipout.write(data, 0, data.length);
      zipout.closeEntry();
    
      zipentry = new ZipEntry("docProps/core.xml");
      zipout.putNextEntry(zipentry);
      data = docProps_core_xml.getBytes();
      zipout.write(data, 0, data.length);
      zipout.closeEntry();
    
      zipentry = new ZipEntry("_rels/.rels");
      zipout.putNextEntry(zipentry);
      data = _rels_rels_xml.getBytes();
      zipout.write(data, 0, data.length);
      zipout.closeEntry();
    
      zipentry = new ZipEntry("xl/_rels/workbook.xml.rels");
      zipout.putNextEntry(zipentry);
      data = xl_rels_workbook_xml_rels_xml.getBytes();
      zipout.write(data, 0, data.length);
      zipout.closeEntry();
    
      zipentry = new ZipEntry("xl/sharedStrings.xml");
      zipout.putNextEntry(zipentry);
      data = xl_sharedstrings_xml.getBytes();
      zipout.write(data, 0, data.length);
      zipout.closeEntry();
    
      zipentry = new ZipEntry("xl/styles.xml");
      zipout.putNextEntry(zipentry);
      data = xl_styles_xml.getBytes();
      zipout.write(data, 0, data.length);
      zipout.closeEntry();
    
      zipentry = new ZipEntry("xl/workbook.xml");
      zipout.putNextEntry(zipentry);
      data = xl_workbook_xml.getBytes();
      zipout.write(data, 0, data.length);
      zipout.closeEntry();
    
      // preparing the sheet data:
    
      Object[][] sheetData = new Object[][] {
       {"Text", "Value", "Formula"},
       {"Text1", 1.23456, "=SIN(B2)"},
       {"Text2", 2.34567, "=SQRT(B3)"},
       {"Text3", 123.456, "=B4/10"}
      };
      String sheetdata = "<sheetData>";
      int r = 0;
      char c = 'A'; --c;
      for (Object[] rowData : sheetData) {
       sheetdata += "<row r=\"" + ++r + "\">";
       c = 'A'; --c;
       for (Object cellData : rowData) {
        sheetdata += "<c r=\"" + Character.toString(++c) + r + "\"";
        if (cellData instanceof String && ((String)cellData).startsWith("=")) {
         sheetdata += "><f>" + ((String)cellData).replace("=", "") + "</f></c>";
        } else if (cellData instanceof String) {
         sheetdata += " t=\"inlineStr\"><is><t>" + ((String)cellData) + "</t></is></c>";
        } else if (cellData instanceof Double) {
         sheetdata += "><v>" + ((Double)cellData) + "</v></c>";
        }
       }
       sheetdata += "</row>";
      }
      sheetdata += "</sheetData>";
    
      // get the static sheet xml into a buffer for further processing
      StringBuffer xl_worksheets_sheet1_xml_buffer = new StringBuffer(xl_worksheets_sheet1_xml);
    
      // get position of the <dimension ref=\"A1\"/> in the static xl_worksheets_sheet1_xml
      int dimensionstart = xl_worksheets_sheet1_xml_buffer.indexOf("<dimension ref=\"A1\"/>");
      // replace the <dimension ref=\"A1\"/> with the new dimension
      xl_worksheets_sheet1_xml_buffer = xl_worksheets_sheet1_xml_buffer.replace(
       dimensionstart, 
       dimensionstart + "<dimension ref=\"A1\"/>".length(), 
       "<dimension ref=\"A1:" + Character.toString(c) + r + "\"/>");
    
      // get position of the <sheetData/> in the static xl_worksheets_sheet1_xml
      int sheetdatastart = xl_worksheets_sheet1_xml_buffer.indexOf("<sheetData/>");
      // replace the <sheetData/> with the prepared sheet date string
      xl_worksheets_sheet1_xml_buffer = xl_worksheets_sheet1_xml_buffer.replace(
       sheetdatastart, 
       sheetdatastart + "<sheetData/>".length(), 
       sheetdata);
    
      // create the xl/worksheets/sheet1.xml
      zipentry = new ZipEntry("xl/worksheets/sheet1.xml");
      zipout.putNextEntry(zipentry);
      data = xl_worksheets_sheet1_xml_buffer.toString().getBytes();
      zipout.write(data, 0, data.length);
      zipout.closeEntry();
    
      zipout.finish();
    
      // now ByteArrayOutputStream resultout contains the XLSX file data
    
      // writing this data into a file
      try (java.io.FileOutputStream fileout = new java.io.FileOutputStream("test.xlsx")) {
       resultout.writeTo(fileout);
       resultout.close();
      }
    
     }
    }
    
  2. # 3 楼答案

    第一个答案:在服务器端完成

    如果这是不可能的,就使用JExecelAPI——几乎所有读取xlsx文件的东西都会读取xls文件

    其他的Excel库都太大了

    另一个想法是,手动编写csv文件,或者使用许多可用的csv库之一编写。同样,大多数读取Excel文件的应用程序也会读取csv文件

  3. # 4 楼答案

    使用ApachePOI,只需将compile "com.android.support:multidex:1.0.1"添加到build.gradle中的依赖项,即可启用多索引。还需要将multiDexEnabled设置为true。这将消除65k方法的限制

  4. # 5 楼答案

    如果您不需要从任何来源读取xlsx文件,我建议您使用CSV excel,它完全能够将该类型转换为其任何std输出

    即使你需要公式,单元格格式,也有办法在你引用的库中使用它,或者使用你自己的xml解析器,正如我之前的许多人所说,excel格式只是一个包含xml的压缩包。以下是对这些xml的描述:

    https://msdn.microsoft.com/en-us/library/dd979921(v=office.12).aspx

    你会发现excel的格式非常复杂,简单的可追溯性并不是他们的首要任务。因此,使用XPath或JAXB创建自己的受限解析器将是一项繁重的工作,但并非不可能

    但我不明白你为什么要限制方法的数量?如果是关于制作嵌入式软件,在我看来,你不应该使用。xlsx,这是一个复杂而繁重的文件,只是为了保存网格