Browse Source

REPORT-71241 大数据集导出变慢

release/11.0
abel 2 years ago
parent
commit
c286324194
  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.CellType;
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.util.POILogFactory;
import com.fr.third.v2.org.apache.poi.util.POILogger;
@ -201,113 +202,116 @@ public class SheetDataWriter implements Closeable {
_numberLastFlushedRow = Math.max(rownum, _numberLastFlushedRow);
_numberOfCellsOfLastFlushedRow = row.getLastCellNum();
_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();
int columnIndex = 0;
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 {
_out.write("<row");
writeAttribute("r", Integer.toString(rownum + 1));
void beginRow(int rownum, SXSSFRow row,StringBuilder sb) throws IOException {
sb.append("<row");
writeAttribute("r", Integer.toString(rownum + 1), sb);
if (row.hasCustomHeight()) {
writeAttribute("customHeight", "true");
writeAttribute("ht", Float.toString(row.getHeightInPoints()));
writeAttribute("customHeight", "true", sb);
writeAttribute("ht", Float.toString(row.getHeightInPoints()), sb);
}
if (row.getZeroHeight()) {
writeAttribute("hidden", "true");
writeAttribute("hidden", "true", sb);
}
if (row.isFormatted()) {
writeAttribute("s", Integer.toString(row.getRowStyleIndex()));
writeAttribute("customFormat", "1");
writeAttribute("s", Integer.toString(row.getRowStyleIndex()), sb);
writeAttribute("customFormat", "1", sb);
}
if (row.getOutlineLevel() != 0) {
writeAttribute("outlineLevel", Integer.toString(row.getOutlineLevel()));
writeAttribute("outlineLevel", Integer.toString(row.getOutlineLevel()), sb);
}
if (row.getHidden() != null) {
writeAttribute("hidden", row.getHidden() ? "1" : "0");
writeAttribute("hidden", row.getHidden() ? "1" : "0", sb);
}
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;
}
void endRow() throws IOException {
_out.write("</row>\n");
void endRow(StringBuilder sb) throws IOException {
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) {
return;
}
String ref = new CellReference(_rownum, columnIndex).formatAsString();
_out.write("<c");
writeAttribute("r", ref);
sb.append("<c");
writeAttribute("r", ref,sb);
CellStyle cellStyle = cell.getCellStyle();
if (cellStyle.getIndex() != 0) {
// 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
// APIs
writeAttribute("s", Integer.toString(cellStyle.getIndex() & 0xffff));
writeAttribute("s", Integer.toString(cellStyle.getIndex() & 0xffff),sb);
}
CellType cellType = cell.getCellType();
switch (cellType) {
case BLANK: {
_out.write('>');
sb.append('>');
break;
}
case FORMULA: {
switch (cell.getCachedFormulaResultType()) {
case NUMERIC:
writeAttribute("t", "n");
writeAttribute("t", "n",sb);
break;
case STRING:
writeAttribute("t", STCellType.STR.toString());
writeAttribute("t", STCellType.STR.toString(),sb);
break;
case BOOLEAN:
writeAttribute("t", "b");
writeAttribute("t", "b",sb);
break;
case ERROR:
writeAttribute("t", "e");
writeAttribute("t", "e",sb);
break;
}
_out.write("><f>");
outputQuotedString(cell.getCellFormula());
_out.write("</f>");
sb.append("><f>");
outputQuotedString(cell.getCellFormula(),sb);
sb.append("</f>");
switch (cell.getCachedFormulaResultType()) {
case NUMERIC:
double nval = cell.getNumericCellValue();
if (!Double.isNaN(nval)) {
_out.write("<v>");
_out.write(Double.toString(nval));
_out.write("</v>");
sb.append("<v>");
sb.append(Double.toString(nval));
sb.append("</v>");
}
break;
case STRING:
String value = cell.getStringCellValue();
if (value != null && !value.isEmpty()) {
_out.write("<v>");
_out.write(value);
_out.write("</v>");
sb.append("<v>");
sb.append(value);
sb.append("</v>");
}
break;
case BOOLEAN:
_out.write("><v>");
_out.write(cell.getBooleanCellValue() ? "1" : "0");
_out.write("</v>");
sb.append("><v>");
sb.append(cell.getBooleanCellValue() ? "1" : "0");
sb.append("</v>");
break;
case ERROR: {
FormulaError error = FormulaError.forInt(cell.getErrorCellValue());
_out.write("><v>");
_out.write(error.getString());
_out.write("</v>");
sb.append("><v>");
sb.append(error.getString());
sb.append("</v>");
break;
}
}
@ -315,81 +319,81 @@ public class SheetDataWriter implements Closeable {
}
case STRING: {
if (_sharedStringSource != null&& cell.isRichText()) {
XSSFRichTextString rt = new XSSFRichTextString(cell.getStringCellValue());
RichTextString rt = cell.getRichStringCellValue();
int sRef = _sharedStringSource.addSharedStringItem(rt);
writeAttribute("t", STCellType.S.toString());
_out.write("><v>");
_out.write(String.valueOf(sRef));
_out.write("</v>");
writeAttribute("t", STCellType.S.toString(),sb);
sb.append("><v>");
sb.append(String.valueOf(sRef));
sb.append("</v>");
} else {
writeAttribute("t", "inlineStr");
_out.write("><is><t");
writeAttribute("t", "inlineStr",sb);
sb.append("><is><t");
if (hasLeadingTrailingSpaces(cell.getStringCellValue())) {
writeAttribute("xml:space", "preserve");
writeAttribute("xml:space", "preserve",sb);
}
_out.write(">");
outputQuotedString(cell.getStringCellValue());
_out.write("</t></is>");
sb.append(">");
outputQuotedString(cell.getStringCellValue(),sb);
sb.append("</t></is>");
}
break;
}
case NUMERIC_STRING: {
_out.write(" t=\"n\"><v>");
_out.write(cell.getNumericStringCellValue());
_out.write("</v>");
sb.append(" t=\"n\"><v>");
sb.append(cell.getNumericStringCellValue());
sb.append("</v>");
break;
}
case NUMERIC_BIG_DECIMAL: {
_out.write(" t=\"n\">");
_out.write("<v>");
_out.write(cell.getNumericBigDecimalCellValue().toString());
_out.write("</v>");
sb.append(" t=\"n\">");
sb.append("<v>");
sb.append(cell.getNumericBigDecimalCellValue().toString());
sb.append("</v>");
break;
}
case NUMERIC_BIG_INTEGER: {
_out.write(" t=\"n\">");
_out.write("<v>");
_out.write(cell.getNumericBigIntegerCellValue().toString());
_out.write("</v>");
sb.append(" t=\"n\">");
sb.append("<v>");
sb.append(cell.getNumericBigIntegerCellValue().toString());
sb.append("</v>");
break;
}
case NUMERIC: {
writeAttribute("t", "n");
_out.write("><v>");
_out.write(Double.toString(cell.getNumericCellValue()));
_out.write("</v>");
writeAttribute("t", "n",sb);
sb.append("><v>");
sb.append(Double.toString(cell.getNumericCellValue()));
sb.append("</v>");
break;
}
case BOOLEAN: {
writeAttribute("t", "b");
_out.write("><v>");
_out.write(cell.getBooleanCellValue() ? "1" : "0");
_out.write("</v>");
writeAttribute("t", "b",sb);
sb.append("><v>");
sb.append(cell.getBooleanCellValue() ? "1" : "0");
sb.append("</v>");
break;
}
case ERROR: {
FormulaError error = FormulaError.forInt(cell.getErrorCellValue());
writeAttribute("t", "e");
_out.write("><v>");
_out.write(error.getString());
_out.write("</v>");
writeAttribute("t", "e",sb);
sb.append("><v>");
sb.append(error.getString());
sb.append("</v>");
break;
}
default: {
throw new IllegalStateException("Invalid cell type: " + cellType);
}
}
_out.write("</c>");
sb.append("</c>");
}
private void writeAttribute(String name, String value) throws IOException {
_out.write(' ');
_out.write(name);
_out.write("=\"");
_out.write(value);
_out.write('\"');
private void writeAttribute(String name, String value,StringBuilder sb) throws IOException {
sb.append(' ');
sb.append(name);
sb.append("=\"");
sb.append(value);
sb.append('\"');
}
/**
@ -405,7 +409,7 @@ public class SheetDataWriter implements Closeable {
return false;
}
protected void outputQuotedString(String s) throws IOException {
protected void outputQuotedString(String s,StringBuilder sb) throws IOException {
if (s == null || s.length() == 0) {
return;
}
@ -413,29 +417,29 @@ public class SheetDataWriter implements Closeable {
for (String codepoint : new StringCodepointsIterable(s)) {
switch (codepoint) {
case "<":
_out.write("&lt;");
sb.append("&lt;");
break;
case ">":
_out.write("&gt;");
sb.append("&gt;");
break;
case "&":
_out.write("&amp;");
sb.append("&amp;");
break;
case "\"":
_out.write("&quot;");
sb.append("&quot;");
break;
// Special characters
case "\n":
_out.write("&#xa;");
sb.append("&#xa;");
break;
case "\r":
_out.write("&#xd;");
sb.append("&#xd;");
break;
case "\t":
_out.write("&#x9;");
sb.append("&#x9;");
break;
case "\u00A0": // NO-BREAK SPACE
_out.write("&#xa0;");
sb.append("&#xa0;");
break;
default:
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.
// the same rule applies to "not a character" symbols.
if (replaceWithQuestionMark(c)) {
_out.write('?');
sb.append('?');
} else {
_out.write(c);
sb.append(c);
}
} else {
_out.write(codepoint);
sb.append(codepoint);
}
break;
}

Loading…
Cancel
Save