精华内容
下载资源
问答
  • 阅读文本大概需要3分钟。来源:https://www.cnblogs.com/barrywxx/p/10700283.html使用POI或JXLS导出大数据量(百万级)Excel报表常常面临两个问题:1....大数据量导入请参考:Java实现大批量数据...

    阅读文本大概需要3分钟。

    来源:https://www.cnblogs.com/barrywxx/p/10700283.html

    使用POI或JXLS导出大数据量(百万级)Excel报表常常面临两个问题:

    1. 服务器内存溢出;

    2. 一次从数据库查询出这么大数据,查询缓慢。

    当然也可以分页查询出数据,分别生成多个Excel打包下载,但这种生成还是很缓慢。

    大数据量导入请参考:Java实现大批量数据导入导出(100W以上) -(一)导入

    那么如何解决呢?

    我们可以借助XML格式利用模板替换,分页查询出数据从磁盘写入XML,最终会以Excel多sheet形式生成。亲测2400万行数据,生成Excel文件4.5G,总耗时1.5分钟

    https://www.cnblogs.com/barrywxx/p/10700283.html 

    我利用StringTemplate模板解析技术对XML模板进行填充。当然也可以使用FreeMarker, Velocity等Java模板技术实现。

    首先引入StringTemplate所需Jar包:

    使用技术为 stringTemplate 

    pom.xml:

    1. antlr

    2. antlr

    3. 2.7.7

    4. org.antlr

    5. stringtemplate

    6. 3.2.1

    首先准备导出Excel模板,然后打开-》另存为-》选择格式为XML,然后用文本打开XML,提取XML头模板(head.st可通用),数据体模板(boday.st):

    head.st可通用:

    1. xml version="1.0"?>

    2. mso-application progid="Excel.Sheet"?>

    3. xmlns="urn:schemas-microsoft-com:office:spreadsheet"

    4. xmlns:o="urn:schemas-microsoft-com:office:office"

    5. xmlns:x="urn:schemas-microsoft-com:office:excel"

    6. xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"

    7. xmlns:html="http://www.w3.org/TR/REC-html40">

    8. xmlns="urn:schemas-microsoft-com:office:office">

    9. 1996-12-17T01:32:42Z

    10. 2013-08-02T09:21:24Z

    11. 11.9999

    12. xmlns="urn:schemas-microsoft-com:office:office">

    13. xmlns="urn:schemas-microsoft-com:office:excel">

    14. 4530

    15. 8505

    16. 480

    17. 120

    18. False

    19. False

    20. ss:ID="Default" ss:Name="Normal">

    21. ss:Vertical="Bottom"/>

    22. ss:FontName="宋体" x:CharSet="134" ss:Size="12"/>

    生成大数据量Excel类:

    ExcelGenerator:

    1. package test.exportexcel;

    2. import org.antlr.stringtemplate.StringTemplate;

    3. import org.antlr.stringtemplate.StringTemplateGroup;

    4. import test.exportexcel.bean.Row;

    5. import test.exportexcel.bean.Worksheet;

    6. import java.io.*;

    7. import java.util.ArrayList;

    8. import java.util.List;

    9. import java.util.Random;

    10. /**

    11. * 类功能描述:generator big data Excel

    12. *

    13. * @author WangXueXing create at 19-4-13 下午10:23

    14. * @version 1.0.0

    15. */

    16. public class ExcelGenerator {

    17. public static void main(String[] args) throws FileNotFoundException{

    18. ExcelGenerator template = new ExcelGenerator();

    19. template.output2();

    20. }

    21. /**

    22. * 生成数据量大的时候,该方法会出现内存溢出

    23. * @throws FileNotFoundException

    24. */

    25. public void output1() throws FileNotFoundException{

    26. StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");

    27. StringTemplate st4 = stGroup.getInstanceOf("test/exportexcel/template/test");

    28. List<Worksheet> worksheets = new ArrayList<>();

    29. File file = new File("/home/barry/data/output.xls");

    30. PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));

    31. for(int i=0;i<30;i++){

    32. Worksheet worksheet = new Worksheet();

    33. worksheet.setSheet("第"+(i+1)+"页");

    34. List<Row> rows = new ArrayList<>();

    35. for(int j=0;j<6000;j++){

    36. Row row = new Row();

    37. row.setName1("zhangzehao");

    38. row.setName2(""+j);

    39. row.setName3(i+" "+j);

    40. rows.add(row);

    41. }

    42. worksheet.setRows(rows);

    43. worksheets.add(worksheet);

    44. }

    45. st4.setAttribute("worksheets", worksheets);

    46. writer.write(st4.toString());

    47. writer.flush();

    48. writer.close();

    49. System.out.println("生成excel完成");

    50. }

    51. /**

    52. * 该方法不管生成多大的数据量,都不会出现内存溢出,只是时间的长短

    53. * 经测试,生成2400万数据,2分钟内,4.5G大的文件,打开大文件就看内存是否足够大了

    54. * 数据量小的时候,推荐用JXLS的模板技术生成excel文件,谁用谁知道,大数据量可以结合该方法使用

    55. * @throws FileNotFoundException

    56. */

    57. public void output2() throws FileNotFoundException{

    58. long startTimne = System.currentTimeMillis();

    59. StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");

    60. //写入excel文件头部信息

    61. StringTemplate head = stGroup.getInstanceOf("test/exportexcel/template/head");

    62. File file = new File("/home/barry/data/output.xls");

    63. PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));

    64. writer.print(head.toString());

    65. writer.flush();

    66. int sheets = 400;

    67. //excel单表最大行数是65535

    68. int maxRowNum = 60000;

    69. //写入excel文件数据信息

    70. for(int i=0;i<sheets;i++){

    71. StringTemplate body = stGroup.getInstanceOf("test/exportexcel/template/body");

    72. Worksheet worksheet = new Worksheet();

    73. worksheet.setSheet(" "+(i+1)+" ");

    74. worksheet.setColumnNum(3);

    75. worksheet.setRowNum(maxRowNum);

    76. List<Row> rows = new ArrayList<>();

    77. for(int j=0;j<maxRowNum;j++){

    78. Row row = new Row();

    79. row.setName1(""+new Random().nextInt(100000));

    80. row.setName2(""+j);

    81. row.setName3(i+""+j);

    82. rows.add(row);

    83. }

    84. worksheet.setRows(rows);

    85. body.setAttribute("worksheet", worksheet);

    86. writer.print(body.toString());

    87. writer.flush();

    88. rows.clear();

    89. rows = null;

    90. worksheet = null;

    91. body = null;

    92. Runtime.getRuntime().gc();

    93. System.out.println("正在生成excel文件的 sheet"+(i+1));

    94. }

    95. //写入excel文件尾部

    96. writer.print("");

    97. writer.flush();

    98. writer.close();

    99. System.out.println("生成excel文件完成");

    100. long endTime = System.currentTimeMillis();

    101. System.out.println("用时="+((endTime-startTimne)/1000)+"秒");

    102. }

    103. }

    定义JavaBean:

    WorkSheet.java:

    1. package test.exportexcel.bean;

    2. import java.util.List;

    3. /**

    4. * 类功能描述:Excel sheet Bean

    5. *

    6. * @author WangXueXing create at 19-4-13 下午10:21

    7. * @version 1.0.0

    8. */

    9. public class Worksheet {

    10. private String sheet;

    11. private int columnNum;

    12. private int rowNum;

    13. private List<Row> rows;

    14. public String getSheet() {

    15. return sheet;

    16. }

    17. public void setSheet(String sheet) {

    18. this.sheet = sheet;

    19. }

    20. public List<Row> getRows() {

    21. return rows;

    22. }

    23. public void setRows(List<Row> rows) {

    24. this.rows = rows;

    25. }

    26. public int getColumnNum() {

    27. return columnNum;

    28. }

    29. public void setColumnNum(int columnNum) {

    30. this.columnNum = columnNum;

    31. }

    32. public int getRowNum() {

    33. return rowNum;

    34. }

    35. public void setRowNum(int rowNum) {

    36. this.rowNum = rowNum;

    37. }

    38. }

    Row.java:

    1. package test.exportexcel.bean;

    2. /**

    3. * 类功能描述:Excel row bean

    4. *

    5. * @author WangXueXing create at 19-4-13 下午10:22

    6. * @version 1.0.0

    7. */

    8. public class Row {

    9. private String name1;

    10. private String name2;

    11. private String name3;

    12. public String getName1() {

    13. return name1;

    14. }

    15. public void setName1(String name1) {

    16. this.name1 = name1;

    17. }

    18. public String getName2() {

    19. return name2;

    20. }

    21. public void setName2(String name2) {

    22. this.name2 = name2;

    23. }

    24. public String getName3() {

    25. return name3;

    26. }

    27. public void setName3(String name3) {

    28. this.name3 = name3;

    29. }

    30. }

    另附实现源码:

    https://files.cnblogs.com/files/barrywxx/exportexcel.zip

    往期精彩

    01 漫谈发版哪些事,好课程推荐

    02 Linux的常用最危险的命令

    03 精讲Spring Boot—入门+进阶+实例

    04 优秀的Java程序员必须了解的GC哪些

    05 互联网支付系统整体架构详解

    关注我

    每天进步一点点

    108b997edec9fe99aef423c1fc7405e7.png

    喜欢!在看☟
    展开全文
  • 阅读文本大概需要3分钟。来源:https://www.cnblogs.com/barrywxx/p/10700283.html使用POI或JXLS导出大数据量(百万级)Excel报表常常面临两个问题:1....大数据量导入请参考:Java实现大批量数据...

    阅读文本大概需要3分钟。

    来源:https://www.cnblogs.com/barrywxx/p/10700283.html

    使用POI或JXLS导出大数据量(百万级)Excel报表常常面临两个问题:

    1. 服务器内存溢出;

    2. 一次从数据库查询出这么大数据,查询缓慢。

    当然也可以分页查询出数据,分别生成多个Excel打包下载,但这种生成还是很缓慢。

    大数据量导入请参考:Java实现大批量数据导入导出(100W以上) -(一)导入

    那么如何解决呢?

    我们可以借助XML格式利用模板替换,分页查询出数据从磁盘写入XML,最终会以Excel多sheet形式生成。亲测2400万行数据,生成Excel文件4.5G,总耗时1.5分钟

    https://www.cnblogs.com/barrywxx/p/10700283.html 

    我利用StringTemplate模板解析技术对XML模板进行填充。当然也可以使用FreeMarker, Velocity等Java模板技术实现。

    首先引入StringTemplate所需Jar包:

    使用技术为 stringTemplate 

    pom.xml:

    1. antlr

    2. antlr

    3. 2.7.7

    4. org.antlr

    5. stringtemplate

    6. 3.2.1

    首先准备导出Excel模板,然后打开-》另存为-》选择格式为XML,然后用文本打开XML,提取XML头模板(head.st可通用),数据体模板(boday.st):

    head.st可通用:

    1. xml version="1.0"?>

    2. mso-application progid="Excel.Sheet"?>

    3. xmlns="urn:schemas-microsoft-com:office:spreadsheet"

    4. xmlns:o="urn:schemas-microsoft-com:office:office"

    5. xmlns:x="urn:schemas-microsoft-com:office:excel"

    6. xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"

    7. xmlns:html="http://www.w3.org/TR/REC-html40">

    8. xmlns="urn:schemas-microsoft-com:office:office">

    9. 1996-12-17T01:32:42Z

    10. 2013-08-02T09:21:24Z

    11. 11.9999

    12. xmlns="urn:schemas-microsoft-com:office:office">

    13. xmlns="urn:schemas-microsoft-com:office:excel">

    14. 4530

    15. 8505

    16. 480

    17. 120

    18. False

    19. False

    20. ss:ID="Default" ss:Name="Normal">

    21. ss:Vertical="Bottom"/>

    22. ss:FontName="宋体" x:CharSet="134" ss:Size="12"/>

    生成大数据量Excel类:

    ExcelGenerator:

    1. package test.exportexcel;

    2. import org.antlr.stringtemplate.StringTemplate;

    3. import org.antlr.stringtemplate.StringTemplateGroup;

    4. import test.exportexcel.bean.Row;

    5. import test.exportexcel.bean.Worksheet;

    6. import java.io.*;

    7. import java.util.ArrayList;

    8. import java.util.List;

    9. import java.util.Random;

    10. /**

    11. * 类功能描述:generator big data Excel

    12. *

    13. * @author WangXueXing create at 19-4-13 下午10:23

    14. * @version 1.0.0

    15. */

    16. public class ExcelGenerator {

    17. public static void main(String[] args) throws FileNotFoundException{

    18. ExcelGenerator template = new ExcelGenerator();

    19. template.output2();

    20. }

    21. /**

    22. * 生成数据量大的时候,该方法会出现内存溢出

    23. * @throws FileNotFoundException

    24. */

    25. public void output1() throws FileNotFoundException{

    26. StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");

    27. StringTemplate st4 = stGroup.getInstanceOf("test/exportexcel/template/test");

    28. List<Worksheet> worksheets = new ArrayList<>();

    29. File file = new File("/home/barry/data/output.xls");

    30. PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));

    31. for(int i=0;i<30;i++){

    32. Worksheet worksheet = new Worksheet();

    33. worksheet.setSheet("第"+(i+1)+"页");

    34. List<Row> rows = new ArrayList<>();

    35. for(int j=0;j<6000;j++){

    36. Row row = new Row();

    37. row.setName1("zhangzehao");

    38. row.setName2(""+j);

    39. row.setName3(i+" "+j);

    40. rows.add(row);

    41. }

    42. worksheet.setRows(rows);

    43. worksheets.add(worksheet);

    44. }

    45. st4.setAttribute("worksheets", worksheets);

    46. writer.write(st4.toString());

    47. writer.flush();

    48. writer.close();

    49. System.out.println("生成excel完成");

    50. }

    51. /**

    52. * 该方法不管生成多大的数据量,都不会出现内存溢出,只是时间的长短

    53. * 经测试,生成2400万数据,2分钟内,4.5G大的文件,打开大文件就看内存是否足够大了

    54. * 数据量小的时候,推荐用JXLS的模板技术生成excel文件,谁用谁知道,大数据量可以结合该方法使用

    55. * @throws FileNotFoundException

    56. */

    57. public void output2() throws FileNotFoundException{

    58. long startTimne = System.currentTimeMillis();

    59. StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");

    60. //写入excel文件头部信息

    61. StringTemplate head = stGroup.getInstanceOf("test/exportexcel/template/head");

    62. File file = new File("/home/barry/data/output.xls");

    63. PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));

    64. writer.print(head.toString());

    65. writer.flush();

    66. int sheets = 400;

    67. //excel单表最大行数是65535

    68. int maxRowNum = 60000;

    69. //写入excel文件数据信息

    70. for(int i=0;i<sheets;i++){

    71. StringTemplate body = stGroup.getInstanceOf("test/exportexcel/template/body");

    72. Worksheet worksheet = new Worksheet();

    73. worksheet.setSheet(" "+(i+1)+" ");

    74. worksheet.setColumnNum(3);

    75. worksheet.setRowNum(maxRowNum);

    76. List<Row> rows = new ArrayList<>();

    77. for(int j=0;j<maxRowNum;j++){

    78. Row row = new Row();

    79. row.setName1(""+new Random().nextInt(100000));

    80. row.setName2(""+j);

    81. row.setName3(i+""+j);

    82. rows.add(row);

    83. }

    84. worksheet.setRows(rows);

    85. body.setAttribute("worksheet", worksheet);

    86. writer.print(body.toString());

    87. writer.flush();

    88. rows.clear();

    89. rows = null;

    90. worksheet = null;

    91. body = null;

    92. Runtime.getRuntime().gc();

    93. System.out.println("正在生成excel文件的 sheet"+(i+1));

    94. }

    95. //写入excel文件尾部

    96. writer.print("");

    97. writer.flush();

    98. writer.close();

    99. System.out.println("生成excel文件完成");

    100. long endTime = System.currentTimeMillis();

    101. System.out.println("用时="+((endTime-startTimne)/1000)+"秒");

    102. }

    103. }

    定义JavaBean:

    WorkSheet.java:

    1. package test.exportexcel.bean;

    2. import java.util.List;

    3. /**

    4. * 类功能描述:Excel sheet Bean

    5. *

    6. * @author WangXueXing create at 19-4-13 下午10:21

    7. * @version 1.0.0

    8. */

    9. public class Worksheet {

    10. private String sheet;

    11. private int columnNum;

    12. private int rowNum;

    13. private List<Row> rows;

    14. public String getSheet() {

    15. return sheet;

    16. }

    17. public void setSheet(String sheet) {

    18. this.sheet = sheet;

    19. }

    20. public List<Row> getRows() {

    21. return rows;

    22. }

    23. public void setRows(List<Row> rows) {

    24. this.rows = rows;

    25. }

    26. public int getColumnNum() {

    27. return columnNum;

    28. }

    29. public void setColumnNum(int columnNum) {

    30. this.columnNum = columnNum;

    31. }

    32. public int getRowNum() {

    33. return rowNum;

    34. }

    35. public void setRowNum(int rowNum) {

    36. this.rowNum = rowNum;

    37. }

    38. }

    Row.java:

    1. package test.exportexcel.bean;

    2. /**

    3. * 类功能描述:Excel row bean

    4. *

    5. * @author WangXueXing create at 19-4-13 下午10:22

    6. * @version 1.0.0

    7. */

    8. public class Row {

    9. private String name1;

    10. private String name2;

    11. private String name3;

    12. public String getName1() {

    13. return name1;

    14. }

    15. public void setName1(String name1) {

    16. this.name1 = name1;

    17. }

    18. public String getName2() {

    19. return name2;

    20. }

    21. public void setName2(String name2) {

    22. this.name2 = name2;

    23. }

    24. public String getName3() {

    25. return name3;

    26. }

    27. public void setName3(String name3) {

    28. this.name3 = name3;

    29. }

    30. }

    另附实现源码:

    https://files.cnblogs.com/files/barrywxx/exportexcel.zip

    往期精彩

    01 漫谈发版哪些事,好课程推荐

    02 Linux的常用最危险的命令

    03 精讲Spring Boot—入门+进阶+实例

    04 优秀的Java程序员必须了解的GC哪些

    05 互联网支付系统整体架构详解

    关注我

    每天进步一点点

    6ced1ead76bf0cbc715078a5c459bda6.png

    喜欢!在看☟
    展开全文
  • 阅读文本大概需要3分钟。来源:https://www.cnblogs.com/barrywxx/p/10700283.html使用POI或JXLS导出大数据量(百万级)Excel报表常常...

    阅读文本大概需要3分钟。

    来源:https://www.cnblogs.com/barrywxx/p/10700283.html

    使用POI或JXLS导出大数据量(百万级)Excel报表常常面临两个问题:

    1. 服务器内存溢出;

    2. 一次从数据库查询出这么大数据,查询缓慢。

    当然也可以分页查询出数据,分别生成多个Excel打包下载,但这种生成还是很缓慢。

    大数据量导入请参考:Java实现大批量数据导入导出(100W以上) -(一)导入

    那么如何解决呢?

    我们可以借助XML格式利用模板替换,分页查询出数据从磁盘写入XML,最终会以Excel多sheet形式生成。亲测2400万行数据,生成Excel文件4.5G,总耗时1.5分钟

    https://www.cnblogs.com/barrywxx/p/10700283.html 

    我利用StringTemplate模板解析技术对XML模板进行填充。当然也可以使用FreeMarker, Velocity等Java模板技术实现。

    首先引入StringTemplate所需Jar包:

    使用技术为 stringTemplate 

    pom.xml:

    1. <dependency>

    2. <groupId>antlr</groupId>

    3. <artifactId>antlr</artifactId>

    4. <version>2.7.7</version>

    5. </dependency>

    6. <dependency>

    7. <groupId>org.antlr</groupId>

    8. <artifactId>stringtemplate</artifactId>

    9. <version>3.2.1</version>

      </dependency>

    首先准备导出Excel模板,然后打开-》另存为-》选择格式为XML,然后用文本打开XML,提取XML头模板(head.st可通用),数据体模板(boday.st):

    head.st可通用:

     

    1. <?xml version="1.0"?>

    2. <?mso-application progid="Excel.Sheet"?>

    3. <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"

    4. xmlns:o="urn:schemas-microsoft-com:office:office"

    5. xmlns:x="urn:schemas-microsoft-com:office:excel"

    6. xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"

    7. xmlns:html="http://www.w3.org/TR/REC-html40">

    8. <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">

    9. <Created>1996-12-17T01:32:42Z</Created>

    10. <LastSaved>2013-08-02T09:21:24Z</LastSaved>

    11. <Version>11.9999</Version>

    12. </DocumentProperties>

    13. <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">

    14. <RemovePersonalInformation/>

    15. </OfficeDocumentSettings>

    16. <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">

    17. <WindowHeight>4530</WindowHeight>

    18. <WindowWidth>8505</WindowWidth>

    19. <WindowTopX>480</WindowTopX>

    20. <WindowTopY>120</WindowTopY>

    21. <AcceptLabelsInFormulas/>

    22. <ProtectStructure>False</ProtectStructure>

    23. <ProtectWindows>False</ProtectWindows>

    24. </ExcelWorkbook>

    25. <Styles>

    26. <Style ss:ID="Default" ss:Name="Normal">

    27. <Alignment ss:Vertical="Bottom"/>

    28. <Borders/>

    29. <Font ss:FontName="宋体" x:CharSet="134" ss:Size="12"/>

    30. <Interior/>

    31. <NumberFormat/>

    32. <Protection/>

    33. </Style>

    34. </Styles>

    生成大数据量Excel类:

    ExcelGenerator:

     

    1. package test.exportexcel;

    2. import org.antlr.stringtemplate.StringTemplate;

    3. import org.antlr.stringtemplate.StringTemplateGroup;

    4. import test.exportexcel.bean.Row;

    5. import test.exportexcel.bean.Worksheet;

    6. import java.io.*;

    7. import java.util.ArrayList;

    8. import java.util.List;

    9. import java.util.Random;

    10. /**

    11. * 类功能描述:generator big data Excel

    12. *

    13. * @author WangXueXing create at 19-4-13 下午10:23

    14. * @version 1.0.0

    15. */

    16. public class ExcelGenerator {

    17. public static void main(String[] args) throws FileNotFoundException{

    18. ExcelGenerator template = new ExcelGenerator();

    19. template.output2();

    20. }

    21. /**

    22. * 生成数据量大的时候,该方法会出现内存溢出

    23. * @throws FileNotFoundException

    24. */

    25. public void output1() throws FileNotFoundException{

    26. StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");

    27. StringTemplate st4 = stGroup.getInstanceOf("test/exportexcel/template/test");

    28. List<Worksheet> worksheets = new ArrayList<>();

    29. File file = new File("/home/barry/data/output.xls");

    30. PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));

    31. for(int i=0;i<30;i++){

    32. Worksheet worksheet = new Worksheet();

    33. worksheet.setSheet("第"+(i+1)+"页");

    34. List<Row> rows = new ArrayList<>();

    35. for(int j=0;j<6000;j++){

    36. Row row = new Row();

    37. row.setName1("zhangzehao");

    38. row.setName2(""+j);

    39. row.setName3(i+" "+j);

    40. rows.add(row);

    41. }

    42. worksheet.setRows(rows);

    43. worksheets.add(worksheet);

    44. }

    45. st4.setAttribute("worksheets", worksheets);

    46. writer.write(st4.toString());

    47. writer.flush();

    48. writer.close();

    49. System.out.println("生成excel完成");

    50. }

    51. /**

    52. * 该方法不管生成多大的数据量,都不会出现内存溢出,只是时间的长短

    53. * 经测试,生成2400万数据,2分钟内,4.5G大的文件,打开大文件就看内存是否足够大了

    54. * 数据量小的时候,推荐用JXLS的模板技术生成excel文件,谁用谁知道,大数据量可以结合该方法使用

    55. * @throws FileNotFoundException

    56. */

    57. public void output2() throws FileNotFoundException{

    58. long startTimne = System.currentTimeMillis();

    59. StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");

    60. //写入excel文件头部信息

    61. StringTemplate head = stGroup.getInstanceOf("test/exportexcel/template/head");

    62. File file = new File("/home/barry/data/output.xls");

    63. PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));

    64. writer.print(head.toString());

    65. writer.flush();

    66. int sheets = 400;

    67. //excel单表最大行数是65535

    68. int maxRowNum = 60000;

    69. //写入excel文件数据信息

    70. for(int i=0;i<sheets;i++){

    71. StringTemplate body = stGroup.getInstanceOf("test/exportexcel/template/body");

    72. Worksheet worksheet = new Worksheet();

    73. worksheet.setSheet(" "+(i+1)+" ");

    74. worksheet.setColumnNum(3);

    75. worksheet.setRowNum(maxRowNum);

    76. List<Row> rows = new ArrayList<>();

    77. for(int j=0;j<maxRowNum;j++){

    78. Row row = new Row();

    79. row.setName1(""+new Random().nextInt(100000));

    80. row.setName2(""+j);

    81. row.setName3(i+""+j);

    82. rows.add(row);

    83. }

    84. worksheet.setRows(rows);

    85. body.setAttribute("worksheet", worksheet);

    86. writer.print(body.toString());

    87. writer.flush();

    88. rows.clear();

    89. rows = null;

    90. worksheet = null;

    91. body = null;

    92. Runtime.getRuntime().gc();

    93. System.out.println("正在生成excel文件的 sheet"+(i+1));

    94. }

    95. //写入excel文件尾部

    96. writer.print("</Workbook>");

    97. writer.flush();

    98. writer.close();

    99. System.out.println("生成excel文件完成");

    100. long endTime = System.currentTimeMillis();

    101. System.out.println("用时="+((endTime-startTimne)/1000)+"秒");

    102. }

    103. }

    定义JavaBean:

    WorkSheet.java:

    1. package test.exportexcel.bean;

    2. import java.util.List;

    3. /**

    4. * 类功能描述:Excel sheet Bean

    5. *

    6. * @author WangXueXing create at 19-4-13 下午10:21

    7. * @version 1.0.0

    8. */

    9. public class Worksheet {

    10. private String sheet;

    11. private int columnNum;

    12. private int rowNum;

    13. private List<Row> rows;

    14. public String getSheet() {

    15. return sheet;

    16. }

    17. public void setSheet(String sheet) {

    18. this.sheet = sheet;

    19. }

    20. public List<Row> getRows() {

    21. return rows;

    22. }

    23. public void setRows(List<Row> rows) {

    24. this.rows = rows;

    25. }

    26. public int getColumnNum() {

    27. return columnNum;

    28. }

    29. public void setColumnNum(int columnNum) {

    30. this.columnNum = columnNum;

    31. }

    32. public int getRowNum() {

    33. return rowNum;

    34. }

    35. public void setRowNum(int rowNum) {

    36. this.rowNum = rowNum;

    37. }

    38. }

    Row.java:

    1. package test.exportexcel.bean;

    2. /**

    3. * 类功能描述:Excel row bean

    4. *

    5. * @author WangXueXing create at 19-4-13 下午10:22

    6. * @version 1.0.0

    7. */

    8. public class Row {

    9. private String name1;

    10. private String name2;

    11. private String name3;

    12. public String getName1() {

    13. return name1;

    14. }

    15. public void setName1(String name1) {

    16. this.name1 = name1;

    17. }

    18. public String getName2() {

    19. return name2;

    20. }

    21. public void setName2(String name2) {

    22. this.name2 = name2;

    23. }

    24. public String getName3() {

    25. return name3;

    26. }

    27. public void setName3(String name3) {

    28. this.name3 = name3;

    29. }

    30. }

    另附实现源码:

    https://files.cnblogs.com/files/barrywxx/exportexcel.zip

    往期精彩

    01 漫谈发版哪些事,好课程推荐

    02 Linux的常用最危险的命令

    03 精讲Spring&nbsp;Boot—入门+进阶+实例

    04 优秀的Java程序员必须了解的GC哪些

    05 互联网支付系统整体架构详解

    关注我

    每天进步一点点

    喜欢!在看☟

    展开全文
  • 使用POI或JXLS导出大数据量(百万级)Excel报表常常面临...大数据量导入请参考:Java实现大批量数据导入导出(100W以上) -(一)导入 那么如何解决呢? 我们可以借助XML格式利用模板替换,分页查询出数据从磁盘写...

    使用POI或JXLS导出大数据量(百万级)Excel报表常常面临两个问题:

    1. 服务器内存溢出;

    2. 一次从数据库查询出这么大数据,查询缓慢。

    当然也可以分页查询出数据,分别生成多个Excel打包下载,但这种生成还是很缓慢。

    大数据量导入请参考:Java实现大批量数据导入导出(100W以上) -(一)导入

    那么如何解决呢?

    我们可以借助XML格式利用模板替换,分页查询出数据从磁盘写入XML,最终会以Excel多sheet形式生成。亲测2400万行数据,生成Excel文件4.5G,总耗时1.5分钟

     

    我利用StringTemplate模板解析技术对XML模板进行填充。当然也可以使用FreeMarker, Velocity等Java模板技术实现。

    首先引入StringTemplate所需Jar包:

    使用技术为 stringTemplate 

    pom.xml:

     1   <dependency>
     2             <groupId>antlr</groupId>
     3             <artifactId>antlr</artifactId>
     4             <version>2.7.7</version>
     5         </dependency>
     6 
     7         <dependency>
     8             <groupId>org.antlr</groupId>
     9             <artifactId>stringtemplate</artifactId>
    10             <version>3.2.1</version>
    11         </dependency>

     

    首先准备导出Excel模板,然后打开-》另存为-》选择格式为XML,然后用文本打开XML,提取XML头模板(head.st可通用),数据体模板(boday.st):

    head.st可通用:

     1 <?xml version="1.0"?>
     2 <?mso-application progid="Excel.Sheet"?>
     3 <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
     4  xmlns:o="urn:schemas-microsoft-com:office:office"
     5  xmlns:x="urn:schemas-microsoft-com:office:excel"
     6  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
     7  xmlns:html="http://www.w3.org/TR/REC-html40">
     8  <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
     9   <Created>1996-12-17T01:32:42Z</Created>
    10   <LastSaved>2013-08-02T09:21:24Z</LastSaved>
    11   <Version>11.9999</Version>
    12  </DocumentProperties>
    13  <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
    14   <RemovePersonalInformation/>
    15  </OfficeDocumentSettings>
    16  <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
    17   <WindowHeight>4530</WindowHeight>
    18   <WindowWidth>8505</WindowWidth>
    19   <WindowTopX>480</WindowTopX>
    20   <WindowTopY>120</WindowTopY>
    21   <AcceptLabelsInFormulas/>
    22   <ProtectStructure>False</ProtectStructure>
    23   <ProtectWindows>False</ProtectWindows>
    24  </ExcelWorkbook>
    25  <Styles>
    26   <Style ss:ID="Default" ss:Name="Normal">
    27    <Alignment ss:Vertical="Bottom"/>
    28    <Borders/>
    29    <Font ss:FontName="宋体" x:CharSet="134" ss:Size="12"/>
    30    <Interior/>
    31    <NumberFormat/>
    32    <Protection/>
    33   </Style>
    34  </Styles>

     

    boday.st:

     

     1  $worksheet:{
     2  <Worksheet ss:Name="$it.sheet$">
     3   <Table ss:ExpandedColumnCount="$it.columnNum$" ss:ExpandedRowCount="$it.rowNum$" x:FullColumns="1"
     4    x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="14.25">
     5  $it.rows:{
     6    <Row>
     7     <Cell><Data ss:Type="String">$it.name1$</Data></Cell>
     8     <Cell><Data ss:Type="String">$it.name2$</Data></Cell>
     9     <Cell><Data ss:Type="String">$it.name3$</Data></Cell>
    10    </Row>
    11  }$
    12   </Table>
    13  </Worksheet>
    14 }$

     

    生成大数据量Excel类:

    ExcelGenerator:

      1 package test.exportexcel;
      2 
      3 import org.antlr.stringtemplate.StringTemplate;
      4 import org.antlr.stringtemplate.StringTemplateGroup;
      5 import test.exportexcel.bean.Row;
      6 import test.exportexcel.bean.Worksheet;
      7 
      8 import java.io.*;
      9 import java.util.ArrayList;
     10 import java.util.List;
     11 import java.util.Random;
     12 
     13 /**
     14  * 类功能描述:generator big data Excel
     15  *
     16  * @author WangXueXing create at 19-4-13 下午10:23
     17  * @version 1.0.0
     18  */
     19 public class ExcelGenerator {
     20     public static void main(String[] args) throws FileNotFoundException{
     21         ExcelGenerator template = new ExcelGenerator();
     22         template.output2();
     23     }
     24 
     25     /**
     26      * 生成数据量大的时候,该方法会出现内存溢出
     27      * @throws FileNotFoundException
     28      */
     29     public void output1() throws FileNotFoundException{
     30         StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");
     31         StringTemplate st4 =  stGroup.getInstanceOf("test/exportexcel/template/test");
     32         List<Worksheet> worksheets = new ArrayList<>();
     33 
     34         File file = new File("/home/barry/data/output.xls");
     35         PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));
     36 
     37         for(int i=0;i<30;i++){
     38             Worksheet worksheet = new Worksheet();
     39             worksheet.setSheet("第"+(i+1)+"页");
     40             List<Row> rows = new ArrayList<>();
     41             for(int j=0;j<6000;j++){
     42                 Row row = new Row();
     43                 row.setName1("zhangzehao");
     44                 row.setName2(""+j);
     45                 row.setName3(i+" "+j);
     46                 rows.add(row);
     47             }
     48             worksheet.setRows(rows);
     49             worksheets.add(worksheet);
     50         }
     51 
     52         st4.setAttribute("worksheets", worksheets);
     53         writer.write(st4.toString());
     54         writer.flush();
     55         writer.close();
     56         System.out.println("生成excel完成");
     57     }
     58 
     59     /**
     60      * 该方法不管生成多大的数据量,都不会出现内存溢出,只是时间的长短
     61      * 经测试,生成2400万数据,2分钟内,4.5G大的文件,打开大文件就看内存是否足够大了
     62      * 数据量小的时候,推荐用JXLS的模板技术生成excel文件,谁用谁知道,大数据量可以结合该方法使用
     63      * @throws FileNotFoundException
     64      */
     65     public void output2() throws FileNotFoundException{
     66         long startTimne = System.currentTimeMillis();
     67         StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");
     68 
     69         //写入excel文件头部信息
     70         StringTemplate head =  stGroup.getInstanceOf("test/exportexcel/template/head");
     71         File file = new File("/home/barry/data/output.xls");
     72         PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));
     73         writer.print(head.toString());
     74         writer.flush();
     75 
     76         int sheets = 400;
     77         //excel单表最大行数是65535
     78         int maxRowNum = 60000;
     79 
     80         //写入excel文件数据信息
     81         for(int i=0;i<sheets;i++){
     82             StringTemplate body =  stGroup.getInstanceOf("test/exportexcel/template/body");
     83             Worksheet worksheet = new Worksheet();
     84             worksheet.setSheet(" "+(i+1)+" ");
     85             worksheet.setColumnNum(3);
     86             worksheet.setRowNum(maxRowNum);
     87             List<Row> rows = new ArrayList<>();
     88             for(int j=0;j<maxRowNum;j++){
     89                 Row row = new Row();
     90                 row.setName1(""+new Random().nextInt(100000));
     91                 row.setName2(""+j);
     92                 row.setName3(i+""+j);
     93                 rows.add(row);
     94             }
     95             worksheet.setRows(rows);
     96             body.setAttribute("worksheet", worksheet);
     97             writer.print(body.toString());
     98             writer.flush();
     99             rows.clear();
    100             rows = null;
    101             worksheet = null;
    102             body = null;
    103             Runtime.getRuntime().gc();
    104             System.out.println("正在生成excel文件的 sheet"+(i+1));
    105         }
    106 
    107         //写入excel文件尾部
    108         writer.print("</Workbook>");
    109         writer.flush();
    110         writer.close();
    111         System.out.println("生成excel文件完成");
    112         long endTime = System.currentTimeMillis();
    113         System.out.println("用时="+((endTime-startTimne)/1000)+"秒");
    114     }
    115 }

     

    定义JavaBean:

    WorkSheet.java:

     1 package test.exportexcel.bean;
     2 
     3 import java.util.List;
     4 
     5 /**
     6  * 类功能描述:Excel sheet Bean
     7  *
     8  * @author WangXueXing create at 19-4-13 下午10:21
     9  * @version 1.0.0
    10  */
    11 public class Worksheet {
    12     private String sheet;
    13     private int columnNum;
    14     private int rowNum;
    15     private List<Row> rows;
    16 
    17     public String getSheet() {
    18         return sheet;
    19     }
    20     public void setSheet(String sheet) {
    21         this.sheet = sheet;
    22     }
    23 
    24     public List<Row> getRows() {
    25         return rows;
    26     }
    27     public void setRows(List<Row> rows) {
    28         this.rows = rows;
    29     }
    30 
    31     public int getColumnNum() {
    32         return columnNum;
    33     }
    34     public void setColumnNum(int columnNum) {
    35         this.columnNum = columnNum;
    36     }
    37 
    38     public int getRowNum() {
    39         return rowNum;
    40     }
    41     public void setRowNum(int rowNum) {
    42         this.rowNum = rowNum;
    43     }
    44 }

     

    Row.java:

     1 package test.exportexcel.bean;
     2 
     3 /**
     4  * 类功能描述:Excel row bean
     5  *
     6  * @author WangXueXing create at 19-4-13 下午10:22
     7  * @version 1.0.0
     8  */
     9 public class Row {
    10     private String name1;
    11     private String name2;
    12     private String name3;
    13 
    14     public String getName1() {
    15         return name1;
    16     }
    17     public void setName1(String name1) {
    18         this.name1 = name1;
    19     }
    20 
    21     public String getName2() {
    22         return name2;
    23     }
    24     public void setName2(String name2) {
    25         this.name2 = name2;
    26     }
    27 
    28     public String getName3() {
    29         return name3;
    30     }
    31     public void setName3(String name3) {
    32         this.name3 = name3;
    33     }
    34 }

     

    另附实现源码: exportexcel.zip

    转载于:https://www.cnblogs.com/barrywxx/p/10700283.html

    展开全文
  • 阅读文本大概需要3分钟。来源:https://www.cnblogs.com/barrywxx/p/10700221.html最近业务方有一个需求,需要一次导入超过100万数据到系统数据...
  • 大数据量报表导出请参考:Java实现大批量数据导入导出(100W以上) -(二)导出 一、为什么一定要在代码实现 说说为什么不能通过SQL直接导入到数据库,而是通过程序实现: 首先,这个导入功能开始提供页面导入,...
  • 今天博主在研究Excel大数据导出性能,发现个意外惊喜,给大家分享下。... 以19.5W数据为例,导出耗时36秒 HSSFWorkbook workBook = new HSSFWorkbook(); 另外需要注意一点Excel 2003一个页签只能放65535行...
  • 最近业务方有一个需求,需要一次导入超过100万数据到系统数据库。可能大家首先会想,这么大的数据,干嘛通过程序去实现导入,为什么不直接通过SQL导入到数据库。一、为什么一定要在代码实现说说为什么不能通过SQL...
  • 来源:https://www.cnblogs.com/barrywxx/p/10700221.html最近业务方有一个需求,需要一次导入超过100万数据到系统数据库。可能大家首先会想,这么大的数据,干嘛通过程序去实现导入,为什么不直接通过SQL导入到...
  • 作者:冷冷gg 链接:https://juejin.im/post/5e83f12ce51d4546c82d8b0fEasyExcelEasyExcel是一个基于... 64M内存1分钟内读取75M(46W行25列)的Excel,当然还有急速模式能更快,但是内存占用会在100M多一点spring boot...
  • 来源:https://www.cnblogs.com/barrywxx/p/10700221.html最近业务方有一个需求,需要一次导入超过100万数据到系统数据库。可能大家首先会想,这么大的数据,干嘛通过程序去实现导入,为什么不直接通过SQL导入到...
  • 前一篇文章写了导出Excel并加密,后来我师傅让我尝试100w的数据量,然后就开始动手了,原来的方法肯定不行,虚拟机就直接给炸了,而且效率特别低,到40w左右的数据的时候,就跑不动了。用户体验也是极差的。同时数据...
  • JAVA 百万数据 导出 EXCEL POI,支持 100W 200W 300w等无限量大数据导出,有兴趣的同学可以参考学习,有问题可以咨询QQ450591221
  • 作者:冷冷gg 链接:https://juejin.im/post/5e83f12ce51d4546c82d8b0fEasyExcelEasyExcel是一个基于... 64M内存1分钟内读取75M(46W行25列)的Excel,当然还有急速模式能更快,但是内存占用会在100M多一点spring boot...
  • java导出百万级数据到excel解决方案

    千次阅读 2017-05-07 23:58:12
    1)、一个excel文件能保存多少条数据,2003版的可以保存65536条,2007版时以保存100w条,但是如果用2007版,当文件过大时,打开会相当的耗时,因此不建议使用2007。 2)、当数据量十分庞大时,从数据库读取数据到...
  • 使用如下代码测试100w条数据导出到excel文件,单线程使用17s,多线程使用13s。当然,针对类似方法的使用,有人做过测试,比我的还详细。但是具体到个人,建议你使用的时候还是要自己测试一下。 测试链接 依赖 <!-...
  • poi3.7可以使用XSSFWorkbook导出xlsx格式,数据量可达到100w,经过跟踪代码发现构建数据起始特别快但当数据量到达5w左右时突然变的很慢,最后报出OutOfMemoryError:java heap spacejvm内存溢出错误,调整jvm内存...
  • 我用OSCache缓存,从数据库中加载100w条记录,抛出outOfMemoryException 各位大虾有没有比较好的缓存大量数据的方案啊 100w条数据适合放在内存吗 谢谢了 [b]问题补充:[/b] 我现在查询了两个表的内容,表1的数据...
  • 解决方法 1: 使用poi 3.9 里面的SXSSFWorkbook 进行导出(本人亲测 100W数据 导出加返回给前段页面 大概需要7 8秒左右) 2 调整JVM参数配置 本文章解决方法 采用第一种SXSSFWorkbook 话不多说 直接上代码(git ...
  • 由excel导出引起的cpu 100% 和gc 的问题

    千次阅读 2018-12-29 14:20:11
    大家好,我是烤鸭:  记一次 由excel导出 导致的cpu... 今天业务突然反馈说导出不了了,我试着导出了2w数据,发现页面卡住了,  没有响应了,查日志,报错如下。 java.lang.IllegalStateException: Cannot c...
  • Linux下多线程(scoll slice)导出es中数据然后在内存中进行操作(1000W级),每次程序导出数据到一定程度的时候CPU飙升到100% 原因分析 1. 查看该Java程序的哪一个线程占用的CPU较高: top -Hbp 3557 | awk '/java/ &...
  • 最近做的系统功能要求从oracle中批量...其次,如果真的一次导出200w 系统能否承受住读写压力(内存溢出),包括下载的时间太久(100w模拟数据写入需45s) 第三,导出后的大文件能否正常打开?(Excel07以上最大支持10...
  • java线程池

    2020-03-28 22:03:00
    导出100W数据excel表 解决方案: 在1场景中,如果开启线程去处理,每个线程处理5W条,那么要开启20个线程。 在场景2中,因为处理时间不确定,如果采用同步的方式,最终导致链接超时。那么考虑开启线程处理。等excel生成好...
  • 优质文章,及时送达...64M内存1分钟内读取75M(46W行25列)的Excel,当然还有急速模式能更快,但是内存占用会在100M多一点spring boot stater依赖方便在 web 环境下使用 easyexcel,已上传至 maven 仓库com....
  • poi3.7可以使用XSSFWorkbook导出xlsx格式,数据量可达到100w,经过跟踪代码发现构建数据起始特别快但当数据量到达5w左右时突然变的很慢,最后报出OutOfMemoryError:java heap space jvm内存溢出错误,调整jvm内存...
  • 千万级数据导出Excel

    千次阅读 2020-05-15 16:18:55
    要知道以 .xlsx结尾的excel文件每个sheet 只能写104万左右的数据量,想要写入500W条数据到excel,要么分到多个sheet中,每个sheet存100w左右数据,5个sheet存储完;要么写到五个xlsx文件中,这可能不是想要的。所以...
  • @简单高效 Excel 导出工具 简单高效 Excel 导出工具 ...64M内存1分钟内读取75M(46W行25列)的Excel,当然还有急速模式能更快,但是内存占用会在100M多一点 spring boot stater依赖 方便在 web 环境下使用 ...
  • EasyExcelEasyExcel是一个...64M内存1分钟内读取75M(46W行25列)的Excel,当然还有急速模式能更快,但是内存占用会在100M多一点spring boot starter依赖方便在 web 环境下使用 easyexcel ,已上传至 maven 仓库<de...

空空如也

空空如也

1 2 3
收藏数 51
精华内容 20
关键字:

java导出100w

java 订阅