wangguanquan / eec

A fast and lower memory excel write/read tool.一个非POI底层,支持流式处理的高效且超低内存的Excel读写工具
https://github.com/wangguanquan/eec/wiki
Apache License 2.0
224 stars 58 forks source link

设值workbook或者sheet的format cells为text而不是general #382

Open pocketchew opened 4 months ago

pocketchew commented 4 months ago

有没有办法把整个worksheet或者整个sheet的format cell设值为Text (或者定义例如10个column的1000个row也行) 测试了使用setStyleProcessor只能把有数据的设值为Text

wangguanquan commented 4 months ago

目前没有可以直接设置的方法,不过可以简单修改即可实现。

设置列为文本属性是通过NumFmt实现的,所以首先我们需要添加一个code为‘@’的NumFmt

Workbook workbook = new Workbook();
Styles styles = workbook.getStyles();
int fmt = styles.addNumFmt(NumFmt.of("@")); // 新增一个文本格式NumFmt
final int txtStyle = styles.of(fmt); // 将其添加进样式表

第二步需要自定义一个WorksheetWriter并将上面得到的txtStyle写入col节点上

public class MyXMLWorksheetWriter extends XMLWorksheetWriter {
    int colStyle; // 整列样式
    public MyXMLWorksheetWriter() { }
    public MyXMLWorksheetWriter(int colStyle) {
        this.colStyle = colStyle;
    }
    @Override
    protected void writeCol(String width, int min, int max, int fillSpace, boolean isHide) throws IOException {
        bw.write("<col customWidth=\"1\" width=\"");
        bw.write(width);
        int w = width.length();
        if (isHide) {
            bw.write("\" hidden=\"1");
            w += 11;
        }
        bw.write('"');
        for (int j = fillSpace - w; j-- > 0; ) bw.write(32); // Fill space
        bw.write(" min=\"");
        bw.writeInt(min);
        bw.write("\" max=\"");
        bw.writeInt(max);
        if (colStyle > 0) {
            bw.write("\" style=\"");
            bw.writeInt(colStyle); // <- 将txtStyle写入col节点上
        }
        bw.write("\" bestFit=\"1\"/>");
    }
}

好了,现在你可以使用这个MyXMLWorksheetWriter 来实现文本格式了,整体代码如下

Workbook workbook = new Workbook();
Styles styles = workbook.getStyles();
int fmt = styles.addNumFmt(NumFmt.of("@")); // 新增一个文本格式NumFmt
final int txtStyle = styles.of(fmt); // 将其添加进样式表

workbook.addSheet(new ListSheet<>(new Column(), new Column(), new Column())
    .setSheetWriter(new MyXMLWorksheetWriter(txtStyle))) // <- 使用自定义MyXMLWorksheetWriter并传入txtStyle 
    .writeTo(Paths.get(""));

当然,如果此功能仅少量范围使用则不需要提出一个类

Workbook workbook = new Workbook();
Styles styles = workbook.getStyles();
int fmt = styles.addNumFmt(NumFmt.of("@"));
final int txtStyle = styles.of(fmt);

workbook.addSheet(new ListSheet<>(new Column(), new Column(), new Column()).setSheetWriter(new XMLWorksheetWriter() {
        @Override
        protected void writeCol(String width, int min, int max, int fillSpace, boolean isHide) throws IOException {
            bw.write("<col customWidth=\"1\" width=\"");
            bw.write(width);
            int w = width.length();
            if (isHide) {
                bw.write("\" hidden=\"1");
                w += 11;
            }
            bw.write('"');
            for (int j = fillSpace - w; j-- > 0; ) bw.write(32); // Fill space
            bw.write(" min=\"");
            bw.writeInt(min);
            bw.write("\" max=\"");
            bw.writeInt(max);
            bw.write("\" style=\"");
            bw.writeInt(txtStyle);
            bw.write("\" bestFit=\"1\"/>");
        }
    })).writeTo(defaultTestPath.resolve("1.xlsx"));

如果要设置整个worksheet均为文本则需要特殊处理,xlsx格式共包含16384列,writeCol方法的min和max参数即为列下标,所以我们只需要将最大下标改为16384即可,需要注意的是必须在写有效范围的最后一个列时将max改为16384,你可以使用 columns[columns.length - 1].getRealColIndex()与min进行比较,相同即为最后一列。