论坛首页 Java企业应用论坛

excel的大数据量用POI写入

浏览 4579 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-03-30   最后修改:2011-03-31
有50万的数据需要分析处理。
处理完毕后写入excel中,excel里需要用一个sheet放所有数据(excel用的是2007以后的版本,行数限制从老版的6万多突破到了100多万)
直接写入跑了一会就OUTOFMEMORY了


多番寻找终于找到poi 3.6,这个版本已经支持了使用XSSF(支持07及以后的excel版本)来写入,并且提供了一个DEMO叫BigGridDemo(网上比较多,知名的DEMO)。这玩意使用XML方式先生成数据,然后再和一个xlsx的模版进行合并生成最终的xlsx。这种做法由于生成XML后还进行了压缩,基本上还是比较节省内存资源的。反正我50万数据是跑过了..百万级的数据问题应该也不大..

但BigGridDemo.java(http://libjakarta-poi-java.sourcearchive.com/documentation/3.6plus-pdfsg/BigGridDemo_8java-source.html有源码,google也有一把)
这个例子很方便,仿造它改一下generate方法就好了..
但有个致命的bug,就是没有对String的value进行XMLencode..一旦你的数据里出现了XML的标准字符(一共五个),你的数据格式就会乱掉...

贴一下需要修正的代码(把所有的value都先XMLEncoder一下)

        public void createCell(int columnIndex, String value, int styleIndex) throws IOException {
            String ref = new CellReference(_rownum, columnIndex).formatAsString();
            _out.write("<c r=\"" + ref + "\" t=\"inlineStr\"");
            if (styleIndex != -1) _out.write(" s=\"" + styleIndex + "\"");
            _out.write(">");
            _out.write("<is><t>" + XMLEncoder.encode(value)+ "</t></is>");
            _out.write("</c>");
        }


附上XMLEncoder的实现(模仿htmlEncoder写的)

public class XMLEncoder {

    private static final String[] xmlCode = new String[256];

    static {
        // Special characters
        xmlCode['\''] = "&apos;";
        xmlCode['\"'] = "&quot;"; // double quote
        xmlCode['&'] = "&amp;"; // ampersand
        xmlCode['<'] = "&lt;"; // lower than
        xmlCode['>'] = "&gt;"; // greater than
    }

    /**
     * <p>
     * Encode the given text into xml.
     * </p>
     * 
     * @param string the text to encode
     * @return the encoded string
     */
    public static String encode(String string) {
        if (string == null) return "";
        int n = string.length();
        char character;
        String xmlchar;
        StringBuffer buffer = new StringBuffer();
        // loop over all the characters of the String.
        for (int i = 0; i < n; i++) {
            character = string.charAt(i);
            // the xmlcode of these characters are added to a StringBuffer one by one
            try {
                xmlchar = xmlCode[character];
                if (xmlchar == null) {
                    buffer.append(character);
                } else {
                    buffer.append(xmlCode[character]);
                }
            } catch (ArrayIndexOutOfBoundsException aioobe) {
                buffer.append(character);
            }
        }
        return buffer.toString();
    }

    public static void main(String[] args) {
        String test = "\'\"4&<2>1";
        System.out.println(encode(test));
    }

}
   发表时间:2011-04-12  
我在使用的过程中遇到如果是中文就会报非法字符的错误,请问这个问题如何解决
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics