Browse Source

Pull request #5789: REPORT-71241 大数据集导出变慢

Merge in CORE/base-third from ~ABEL.CHEN/base-third:release/11.0 to release/11.0

* commit 'c2863241947144732c9563d9c3b571fca2d9a8cd':
  REPORT-71241 大数据集导出变慢
release/11.0
abel.chen 3 years ago
parent
commit
c76dd14f78
  1. 192
      fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/xssf/streaming/SheetDataWriter.java

192
fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/xssf/streaming/SheetDataWriter.java

@ -36,6 +36,7 @@ import com.fr.third.v2.org.apache.poi.ss.usermodel.Cell;
import com.fr.third.v2.org.apache.poi.ss.usermodel.CellStyle; import com.fr.third.v2.org.apache.poi.ss.usermodel.CellStyle;
import com.fr.third.v2.org.apache.poi.ss.usermodel.CellType; import com.fr.third.v2.org.apache.poi.ss.usermodel.CellType;
import com.fr.third.v2.org.apache.poi.ss.usermodel.FormulaError; import com.fr.third.v2.org.apache.poi.ss.usermodel.FormulaError;
import com.fr.third.v2.org.apache.poi.ss.usermodel.RichTextString;
import com.fr.third.v2.org.apache.poi.ss.util.CellReference; import com.fr.third.v2.org.apache.poi.ss.util.CellReference;
import com.fr.third.v2.org.apache.poi.util.POILogFactory; import com.fr.third.v2.org.apache.poi.util.POILogFactory;
import com.fr.third.v2.org.apache.poi.util.POILogger; import com.fr.third.v2.org.apache.poi.util.POILogger;
@ -201,113 +202,116 @@ public class SheetDataWriter implements Closeable {
_numberLastFlushedRow = Math.max(rownum, _numberLastFlushedRow); _numberLastFlushedRow = Math.max(rownum, _numberLastFlushedRow);
_numberOfCellsOfLastFlushedRow = row.getLastCellNum(); _numberOfCellsOfLastFlushedRow = row.getLastCellNum();
_numberOfFlushedRows++; _numberOfFlushedRows++;
beginRow(rownum, row); int size = this._numberOfCellsOfLastFlushedRow > 0 ? this._numberOfCellsOfLastFlushedRow : 1;
StringBuilder sb = new StringBuilder(size << 6);
beginRow(rownum, row, sb);
Iterator<Cell> cells = row.allCellsIterator(); Iterator<Cell> cells = row.allCellsIterator();
int columnIndex = 0; int columnIndex = 0;
while (cells.hasNext()) { while (cells.hasNext()) {
writeCell(columnIndex++, cells.next()); writeCell(columnIndex++, cells.next(),sb);
} }
endRow(); endRow(sb);
this._out.write(sb.toString());
} }
void beginRow(int rownum, SXSSFRow row) throws IOException { void beginRow(int rownum, SXSSFRow row,StringBuilder sb) throws IOException {
_out.write("<row"); sb.append("<row");
writeAttribute("r", Integer.toString(rownum + 1)); writeAttribute("r", Integer.toString(rownum + 1), sb);
if (row.hasCustomHeight()) { if (row.hasCustomHeight()) {
writeAttribute("customHeight", "true"); writeAttribute("customHeight", "true", sb);
writeAttribute("ht", Float.toString(row.getHeightInPoints())); writeAttribute("ht", Float.toString(row.getHeightInPoints()), sb);
} }
if (row.getZeroHeight()) { if (row.getZeroHeight()) {
writeAttribute("hidden", "true"); writeAttribute("hidden", "true", sb);
} }
if (row.isFormatted()) { if (row.isFormatted()) {
writeAttribute("s", Integer.toString(row.getRowStyleIndex())); writeAttribute("s", Integer.toString(row.getRowStyleIndex()), sb);
writeAttribute("customFormat", "1"); writeAttribute("customFormat", "1", sb);
} }
if (row.getOutlineLevel() != 0) { if (row.getOutlineLevel() != 0) {
writeAttribute("outlineLevel", Integer.toString(row.getOutlineLevel())); writeAttribute("outlineLevel", Integer.toString(row.getOutlineLevel()), sb);
} }
if (row.getHidden() != null) { if (row.getHidden() != null) {
writeAttribute("hidden", row.getHidden() ? "1" : "0"); writeAttribute("hidden", row.getHidden() ? "1" : "0", sb);
} }
if (row.getCollapsed() != null) { if (row.getCollapsed() != null) {
writeAttribute("collapsed", row.getCollapsed() ? "1" : "0"); writeAttribute("collapsed", row.getCollapsed() ? "1" : "0", sb);
} }
_out.write(">\n"); sb.append(">\n");
this._rownum = rownum; this._rownum = rownum;
} }
void endRow() throws IOException { void endRow(StringBuilder sb) throws IOException {
_out.write("</row>\n"); sb.append("</row>\n");
} }
public void writeCell(int columnIndex, Cell cell) throws IOException { public void writeCell(int columnIndex, Cell cell,StringBuilder sb) throws IOException {
if (cell == null) { if (cell == null) {
return; return;
} }
String ref = new CellReference(_rownum, columnIndex).formatAsString(); String ref = new CellReference(_rownum, columnIndex).formatAsString();
_out.write("<c"); sb.append("<c");
writeAttribute("r", ref); writeAttribute("r", ref,sb);
CellStyle cellStyle = cell.getCellStyle(); CellStyle cellStyle = cell.getCellStyle();
if (cellStyle.getIndex() != 0) { if (cellStyle.getIndex() != 0) {
// need to convert the short to unsigned short as the indexes can be up to 64k // need to convert the short to unsigned short as the indexes can be up to 64k
// ideally we would use int for this index, but that would need changes to some more // ideally we would use int for this index, but that would need changes to some more
// APIs // APIs
writeAttribute("s", Integer.toString(cellStyle.getIndex() & 0xffff)); writeAttribute("s", Integer.toString(cellStyle.getIndex() & 0xffff),sb);
} }
CellType cellType = cell.getCellType(); CellType cellType = cell.getCellType();
switch (cellType) { switch (cellType) {
case BLANK: { case BLANK: {
_out.write('>'); sb.append('>');
break; break;
} }
case FORMULA: { case FORMULA: {
switch (cell.getCachedFormulaResultType()) { switch (cell.getCachedFormulaResultType()) {
case NUMERIC: case NUMERIC:
writeAttribute("t", "n"); writeAttribute("t", "n",sb);
break; break;
case STRING: case STRING:
writeAttribute("t", STCellType.STR.toString()); writeAttribute("t", STCellType.STR.toString(),sb);
break; break;
case BOOLEAN: case BOOLEAN:
writeAttribute("t", "b"); writeAttribute("t", "b",sb);
break; break;
case ERROR: case ERROR:
writeAttribute("t", "e"); writeAttribute("t", "e",sb);
break; break;
} }
_out.write("><f>"); sb.append("><f>");
outputQuotedString(cell.getCellFormula()); outputQuotedString(cell.getCellFormula(),sb);
_out.write("</f>"); sb.append("</f>");
switch (cell.getCachedFormulaResultType()) { switch (cell.getCachedFormulaResultType()) {
case NUMERIC: case NUMERIC:
double nval = cell.getNumericCellValue(); double nval = cell.getNumericCellValue();
if (!Double.isNaN(nval)) { if (!Double.isNaN(nval)) {
_out.write("<v>"); sb.append("<v>");
_out.write(Double.toString(nval)); sb.append(Double.toString(nval));
_out.write("</v>"); sb.append("</v>");
} }
break; break;
case STRING: case STRING:
String value = cell.getStringCellValue(); String value = cell.getStringCellValue();
if (value != null && !value.isEmpty()) { if (value != null && !value.isEmpty()) {
_out.write("<v>"); sb.append("<v>");
_out.write(value); sb.append(value);
_out.write("</v>"); sb.append("</v>");
} }
break; break;
case BOOLEAN: case BOOLEAN:
_out.write("><v>"); sb.append("><v>");
_out.write(cell.getBooleanCellValue() ? "1" : "0"); sb.append(cell.getBooleanCellValue() ? "1" : "0");
_out.write("</v>"); sb.append("</v>");
break; break;
case ERROR: { case ERROR: {
FormulaError error = FormulaError.forInt(cell.getErrorCellValue()); FormulaError error = FormulaError.forInt(cell.getErrorCellValue());
_out.write("><v>"); sb.append("><v>");
_out.write(error.getString()); sb.append(error.getString());
_out.write("</v>"); sb.append("</v>");
break; break;
} }
} }
@ -315,81 +319,81 @@ public class SheetDataWriter implements Closeable {
} }
case STRING: { case STRING: {
if (_sharedStringSource != null&& cell.isRichText()) { if (_sharedStringSource != null&& cell.isRichText()) {
XSSFRichTextString rt = new XSSFRichTextString(cell.getStringCellValue()); RichTextString rt = cell.getRichStringCellValue();
int sRef = _sharedStringSource.addSharedStringItem(rt); int sRef = _sharedStringSource.addSharedStringItem(rt);
writeAttribute("t", STCellType.S.toString()); writeAttribute("t", STCellType.S.toString(),sb);
_out.write("><v>"); sb.append("><v>");
_out.write(String.valueOf(sRef)); sb.append(String.valueOf(sRef));
_out.write("</v>"); sb.append("</v>");
} else { } else {
writeAttribute("t", "inlineStr"); writeAttribute("t", "inlineStr",sb);
_out.write("><is><t"); sb.append("><is><t");
if (hasLeadingTrailingSpaces(cell.getStringCellValue())) { if (hasLeadingTrailingSpaces(cell.getStringCellValue())) {
writeAttribute("xml:space", "preserve"); writeAttribute("xml:space", "preserve",sb);
} }
_out.write(">"); sb.append(">");
outputQuotedString(cell.getStringCellValue()); outputQuotedString(cell.getStringCellValue(),sb);
_out.write("</t></is>"); sb.append("</t></is>");
} }
break; break;
} }
case NUMERIC_STRING: { case NUMERIC_STRING: {
_out.write(" t=\"n\"><v>"); sb.append(" t=\"n\"><v>");
_out.write(cell.getNumericStringCellValue()); sb.append(cell.getNumericStringCellValue());
_out.write("</v>"); sb.append("</v>");
break; break;
} }
case NUMERIC_BIG_DECIMAL: { case NUMERIC_BIG_DECIMAL: {
_out.write(" t=\"n\">"); sb.append(" t=\"n\">");
_out.write("<v>"); sb.append("<v>");
_out.write(cell.getNumericBigDecimalCellValue().toString()); sb.append(cell.getNumericBigDecimalCellValue().toString());
_out.write("</v>"); sb.append("</v>");
break; break;
} }
case NUMERIC_BIG_INTEGER: { case NUMERIC_BIG_INTEGER: {
_out.write(" t=\"n\">"); sb.append(" t=\"n\">");
_out.write("<v>"); sb.append("<v>");
_out.write(cell.getNumericBigIntegerCellValue().toString()); sb.append(cell.getNumericBigIntegerCellValue().toString());
_out.write("</v>"); sb.append("</v>");
break; break;
} }
case NUMERIC: { case NUMERIC: {
writeAttribute("t", "n"); writeAttribute("t", "n",sb);
_out.write("><v>"); sb.append("><v>");
_out.write(Double.toString(cell.getNumericCellValue())); sb.append(Double.toString(cell.getNumericCellValue()));
_out.write("</v>"); sb.append("</v>");
break; break;
} }
case BOOLEAN: { case BOOLEAN: {
writeAttribute("t", "b"); writeAttribute("t", "b",sb);
_out.write("><v>"); sb.append("><v>");
_out.write(cell.getBooleanCellValue() ? "1" : "0"); sb.append(cell.getBooleanCellValue() ? "1" : "0");
_out.write("</v>"); sb.append("</v>");
break; break;
} }
case ERROR: { case ERROR: {
FormulaError error = FormulaError.forInt(cell.getErrorCellValue()); FormulaError error = FormulaError.forInt(cell.getErrorCellValue());
writeAttribute("t", "e"); writeAttribute("t", "e",sb);
_out.write("><v>"); sb.append("><v>");
_out.write(error.getString()); sb.append(error.getString());
_out.write("</v>"); sb.append("</v>");
break; break;
} }
default: { default: {
throw new IllegalStateException("Invalid cell type: " + cellType); throw new IllegalStateException("Invalid cell type: " + cellType);
} }
} }
_out.write("</c>"); sb.append("</c>");
} }
private void writeAttribute(String name, String value) throws IOException { private void writeAttribute(String name, String value,StringBuilder sb) throws IOException {
_out.write(' '); sb.append(' ');
_out.write(name); sb.append(name);
_out.write("=\""); sb.append("=\"");
_out.write(value); sb.append(value);
_out.write('\"'); sb.append('\"');
} }
/** /**
@ -405,7 +409,7 @@ public class SheetDataWriter implements Closeable {
return false; return false;
} }
protected void outputQuotedString(String s) throws IOException { protected void outputQuotedString(String s,StringBuilder sb) throws IOException {
if (s == null || s.length() == 0) { if (s == null || s.length() == 0) {
return; return;
} }
@ -413,29 +417,29 @@ public class SheetDataWriter implements Closeable {
for (String codepoint : new StringCodepointsIterable(s)) { for (String codepoint : new StringCodepointsIterable(s)) {
switch (codepoint) { switch (codepoint) {
case "<": case "<":
_out.write("&lt;"); sb.append("&lt;");
break; break;
case ">": case ">":
_out.write("&gt;"); sb.append("&gt;");
break; break;
case "&": case "&":
_out.write("&amp;"); sb.append("&amp;");
break; break;
case "\"": case "\"":
_out.write("&quot;"); sb.append("&quot;");
break; break;
// Special characters // Special characters
case "\n": case "\n":
_out.write("&#xa;"); sb.append("&#xa;");
break; break;
case "\r": case "\r":
_out.write("&#xd;"); sb.append("&#xd;");
break; break;
case "\t": case "\t":
_out.write("&#x9;"); sb.append("&#x9;");
break; break;
case "\u00A0": // NO-BREAK SPACE case "\u00A0": // NO-BREAK SPACE
_out.write("&#xa0;"); sb.append("&#xa0;");
break; break;
default: default:
if (codepoint.length() == 1) { if (codepoint.length() == 1) {
@ -443,12 +447,12 @@ public class SheetDataWriter implements Closeable {
// YK: XmlBeans silently replaces all ISO control characters ( < 32) with question marks. // YK: XmlBeans silently replaces all ISO control characters ( < 32) with question marks.
// the same rule applies to "not a character" symbols. // the same rule applies to "not a character" symbols.
if (replaceWithQuestionMark(c)) { if (replaceWithQuestionMark(c)) {
_out.write('?'); sb.append('?');
} else { } else {
_out.write(c); sb.append(c);
} }
} else { } else {
_out.write(codepoint); sb.append(codepoint);
} }
break; break;
} }

Loading…
Cancel
Save