Java 我可以使用ApachePOI以流模式将Excel电子表格格式化为表格吗

Java 我可以使用ApachePOI以流模式将Excel电子表格格式化为表格吗,java,excel,apache-poi,Java,Excel,Apache Poi,Excel中的常规电子表格(制表符)可以通过选择数据和ctrl+T(这为每列提供了一个允许筛选值的标题)制成表格 我的电子表格是使用和SXSSF流媒体接口创建的,我必须使用流媒体接口,因为电子表格可能非常大。是否可以通过编程将每个工作表转换为表 我遇到了XSSFTable类,但不清楚如何使用它,也不清楚它是否可以在流模式下使用 package com.jthink.songkong.reports.spreadsheet; import com.jthink.songkong.db.SongC

Excel中的常规电子表格(制表符)可以通过选择数据和ctrl+T(这为每列提供了一个允许筛选值的标题)制成表格

我的电子表格是使用和SXSSF流媒体接口创建的,我必须使用流媒体接口,因为电子表格可能非常大。是否可以通过编程将每个工作表转换为表

我遇到了XSSFTable类,但不清楚如何使用它,也不清楚它是否可以在流模式下使用

package com.jthink.songkong.reports.spreadsheet;

import com.jthink.songkong.db.SongCache;
import com.jthink.songkong.text.SongFieldName;
import com.jthink.songkong.ui.MainWindow;
import com.jthink.songlayer.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.hibernate.Session;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Paul on 09/03/2017.
 */
public class SpreadsheetReport
{
    //Max Width we want to use in chars, whatever the data
    public static final int MAX_COL_WIDTH = 100;

    public static final int COL_WIDTH_MULTIPLIER = 256;
    private static final int FLUSH_SIZE = 1000;
    public static final int FONT_MARGIN_OF_ERROR = 5;
    private String reportName;
    private FileOutputStream fos;
    private int rowCounter =0;
    private SXSSFWorkbook workbook;
    private CellStyle headerStyle;
    private CellStyle fieldAddedStyle;
    private CellStyle fieldChangedStyle;
    private CellStyle fieldDeletedStyle;
    private CellStyle fieldUnchangedStyle;
    private List<Worksheet> worksheets;
    private CreationHelper factory;

    public SpreadsheetReport(String reportName) throws IOException
    {
        this.reportName =reportName;
        //Create new File
        fos = new FileOutputStream(reportName);
        workbook = new SXSSFWorkbook(FLUSH_SIZE);


        factory = workbook.getCreationHelper();

        worksheets = new ArrayList<Worksheet>();
        worksheets.add(0, new BasicWorksheet(workbook));
        worksheets.add(1, new ReleaseWorksheet(workbook));
        worksheets.add(2, new ClassicalWorksheet(workbook));
        worksheets.add(3, new PeopleWorksheet(workbook));
        worksheets.add(4, new SortWorksheet(workbook));
        worksheets.add(5, new MusicBrainzWorksheet(workbook));
        worksheets.add(6, new MusicBrainzWorkWorksheet(workbook));
        worksheets.add(7, new AcousticBrainzWorksheet(workbook));


        Font font = workbook.createFont();
        font.setBold(true);
        headerStyle = workbook.createCellStyle();
        headerStyle.setFont(font);
        headerStyle.setWrapText(true);

        fieldAddedStyle = workbook.createCellStyle();
        fieldAddedStyle.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
        fieldAddedStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        fieldAddedStyle.setWrapText(true);

        fieldChangedStyle = workbook.createCellStyle();
        fieldChangedStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
        fieldChangedStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        fieldChangedStyle.setWrapText(true);

        fieldDeletedStyle = workbook.createCellStyle();
        fieldDeletedStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
        fieldDeletedStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        fieldDeletedStyle.setWrapText(true);

        fieldUnchangedStyle = workbook.createCellStyle();
        fieldUnchangedStyle.setWrapText(true);
    }

    public void writeHeader() throws IOException
    {
        for(Worksheet next:worksheets)
        {
            Row   r = next.getSheet().createRow(rowCounter);
            for(int i=0;i <next.getMapping().size(); i++)
            {
                addHeaderCell(r, i, next.getMapping().get(i));
            }
        }
        rowCounter++;
    }

    private void addHeaderCell(Row r, int spreadsheetIndex, SongFieldNameColumnWidth field)
    {
        Cell cell  = r.createCell(spreadsheetIndex);
        cell.setCellValue(field.getSongFieldName().getName());
        cell.setCellStyle(headerStyle);
    }

    public void writeDatatoXlsFile(Session session, Song song, List<SongChanges> songChanges) throws IOException
    {
        for(Worksheet next:worksheets)
        {
            Row   r = next.getSheet().createRow(rowCounter);
            org.apache.poi.ss.usermodel.Cell c ;
            c=r.createCell(0);
            c.setCellValue(song.getFilename());

            Map<SongFieldKey, SongChanges> fieldToChanges = new HashMap<SongFieldKey, SongChanges>();
            for(SongChanges nextChange:songChanges)
            {
                fieldToChanges.put(nextChange.getField(), nextChange);
            }

            for (int i = 0; i < next.getMapping().size(); i++)
            {
                addFieldValue(session, next , r, i, next.getMapping().get(i), fieldToChanges.get(next.getMapping().get(i).getSongFieldName().getSongFieldKey()), song);
            }
        }
        rowCounter++;
    }

    /**
     * Show the old value as a comment/ttoltip
     * @param r
     * @param c
     * @param sheet
     * @param value
     */
    private void addCellComment(Row r, Cell c, Worksheet sheet, String value)
    {
        String formattedValue    =  value.replace('\u0000', '\n');
        int    rowCount         =  value.split("\\\\u000").length;
        ClientAnchor anchor = factory.createClientAnchor();
        anchor.setCol1(c.getColumnIndex());

        //Wider for filename column
        if(c.getColumnIndex()==0)
        {
            anchor.setCol2(c.getColumnIndex()+5);
        }
        else
        {
            anchor.setCol2(c.getColumnIndex()+2);
        }
        anchor.setRow1(r.getRowNum());
        anchor.setRow2(r.getRowNum()+rowCount);

        // Create the comment and set the text+author
        Drawing drawing = sheet.getDrawing();
        Comment comment = drawing.createCellComment(anchor);
        RichTextString str = factory.createRichTextString(formattedValue);
        comment.setString(str);
        c.setCellComment(comment);

    }
    private void addFieldValue(Session session, Worksheet sheet, Row r, int spreadsheetIndex, SongFieldNameColumnWidth sfncw, SongChanges fieldChanges, Song song)
    {
        SongFieldName   songFieldName = sfncw.getSongFieldName();
        String          value = "";
        org.apache.poi.ss.usermodel.Cell c ;
        c=r.createCell(spreadsheetIndex);

        //Chnanges have been made to this field
        if(fieldChanges!=null)
        {
            SongChangeType changeType = fieldChanges.getType();
            if(songFieldName==SongFieldName.FILENAME)
            {
                value = fieldChanges.getNewValue();
                c.setCellValue(value);
                c.setCellStyle(fieldChangedStyle);
                //addCellComment(r, c, sheet, song.getFilename());
            }
            else if(songFieldName==SongFieldName.COVER_ART)
            {
                if (changeType == SongChangeType.ADD )
                {
                    CoverImage ci = SongCache.findCoverImageByDataKey(session, fieldChanges.getNewValue());
                    if(ci!=null)
                    {
                        value = ci.getWidth() + " x " + ci.getHeight();
                        c.setCellValue(value);
                        c.setCellStyle(fieldAddedStyle);
                    }
                    else
                    {
                        MainWindow.logger.severe("Unable to find coverimage for song:"+song.getRecNo()+":"+song.getFilename());
                    }
                    session.flush();
                }
                else if (changeType == SongChangeType.EDIT)
                {
                    CoverImage ci = SongCache.findCoverImageByDataKey(session, fieldChanges.getNewValue());
                    if(ci!=null)
                    {
                        value = ci.getWidth() + " x " + ci.getHeight();
                        c.setCellValue(value);
                        c.setCellStyle(fieldChangedStyle);
                    }
                    else
                    {
                        MainWindow.logger.severe("Unable to find coverimage for song:"+song.getRecNo()+":"+song.getFilename());
                    }
                    CoverImage ciOrig = SongCache.findCoverImageByDataKey(session, fieldChanges.getOriginalValue());
                    if(ciOrig!=null)
                    {
                        String valueOrig = ciOrig.getWidth() + " x " + ciOrig.getHeight();
                        //addCellComment(r, c, sheet, valueOrig);
                    }
                    session.flush();
                }
                else if (changeType == SongChangeType.NOCHANGE)
                {
                    CoverArt coverart = song.getCoverArts().get(0);
                    value = coverart.getCoverImage().getWidth()+" x" + coverart.getCoverImage().getHeight();
                    c.setCellValue(value);
                    c.setCellStyle(fieldUnchangedStyle);
                }
                else if (changeType == SongChangeType.DELETE)
                {
                    c.setCellStyle(fieldDeletedStyle);
                }
            }
            else
            {
                if (changeType == SongChangeType.ADD)
                {
                    value = fieldChanges.getNewValue().replace('\u0000', '\n');
                    c.setCellValue(value);
                    c.setCellStyle(fieldAddedStyle);

                }
                else if (changeType == SongChangeType.EDIT)
                {
                    value = fieldChanges.getNewValue().replace('\u0000', '\n');
                    c.setCellValue(value);
                    c.setCellStyle(fieldChangedStyle);
                    //addCellComment(r, c, sheet, fieldChanges.getOriginalValue());
                }
                else if (changeType == SongChangeType.DELETE)
                {
                    c.setCellStyle(fieldDeletedStyle);
                }
                else if (changeType == SongChangeType.NOCHANGE)
                {
                    value = fieldChanges.getOriginalValue().replace('\u0000', '\n');
                    c.setCellValue(value);
                    c.setCellStyle(fieldUnchangedStyle);
                    //addCellComment(r, c, sheet, fieldChanges.getOriginalValue());
                }
            }
        }
        //Field is unchanged
        //Note shoud not be called because we now log unchanged fields as well
        else
        {
            if(songFieldName==SongFieldName.FILENAME)
            {
                value = song.getFilename();
                c.setCellValue(value);
            }
            else if(songFieldName==SongFieldName.COVER_ART)
            {
                if(song.getCoverArts().size()>0)
                {
                    CoverArt coverart = song.getCoverArts().get(0);
                    value = coverart.getCoverImage().getWidth()+" x" + coverart.getCoverImage().getHeight();
                    c.setCellValue(value);
                }
            }
            else
            {
                value = song.getFieldValueOrEmptyString(songFieldName.getSongFieldKey()).replace('\u0000', '\n');
                c.setCellStyle(fieldUnchangedStyle);
                c.setCellValue(value);
            }
        }
        sfncw.setColumnWidthFromValue(value);
    }

    public void finish() throws IOException
    {
        for (Worksheet next : worksheets)
        {
            SXSSFSheet sheet = (SXSSFSheet)next.getSheet();

            for (int i = 0; i < next.getMapping().size(); i++)
            {
                int columnWidth = next.getMapping().get(i).getColumnWidthFromValue() + FONT_MARGIN_OF_ERROR;
                columnWidth = columnWidth > MAX_COL_WIDTH ? MAX_COL_WIDTH : columnWidth;
                sheet.setColumnWidth(i, columnWidth * COL_WIDTH_MULTIPLIER);
            }
        }
        workbook.write(fos);
        fos.close();
        workbook.dispose();
    }

}
package com.jthink.songkong.reports.spreadsheet;
导入com.jthink.songkong.db.SongCache;
导入com.jthink.songkong.text.SongFieldName;
导入com.jthink.songkong.ui.main窗口;
导入com.jthink.songlayer.*;
导入org.apache.poi.ss.usermodel.*;
导入org.apache.poi.xssf.streaming.SXSSFSheet;
导入org.apache.poi.xssf.streaming.SXSSFWorkbook;
导入org.hibernate.Session;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
/**
*由Paul于2017年3月9日创建。
*/
公共类电子表格报告
{
//我们希望在字符中使用的最大宽度,无论数据是什么
公共静态最终整数最大列宽=100;
公共静态最终整数列宽度乘数=256;
专用静态最终整流罩尺寸=1000;
公共静态最终整型字体页边空白错误=5;
私有字符串报告名;
私有文件输出流;
私有整数行计数器=0;
私人SXSSF工作手册;
私人牢房式领导风格;
专用单元格样式字段添加样式;
私有单元样式fieldChangedStyle;
私有单元格样式字段删除样式;
私有单元格样式字段未更改样式;
私人名单工作表;
私人创意助手工厂;
公共电子表格报表(字符串reportName)引发IOException
{
this.reportName=reportName;
//创建新文件
fos=新文件输出流(reportName);
工作簿=新的SXSSFWorkbook(刷新大小);
factory=workbook.getCreationHelper();
工作表=新的ArrayList();
工作表。添加(0,新的基本工作表(工作簿));
工作表。添加(1,新发布工作表(工作簿));
工作表。添加(2,新的经典工作表(工作簿));
工作表。添加(3,新人员工作表(工作簿));
工作表。添加(4,新的排序工作表(工作簿));
工作表。添加(5,新的MusicBrainzWorksheet(工作簿));
工作表。添加(6,新的MusicBrainzWorksheet(工作簿));
工作表。添加(7,新的声学工作表(工作簿));
Font=workbook.createFont();
font.setBold(true);
headerStyle=workbook.createCellStyle();
headerStyle.setFont(字体);
headerStyle.setWrapText(真);
fieldAddedStyle=workbook.createCellStyle();
fieldAddedStyle.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());
fieldAddedStyle.setFillPattern(CellStyle.SOLID_前台);
fieldAddedStyle.setWrapText(真);
fieldChangedStyle=workbook.createCellStyle();
fieldChangedStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
fieldChangedStyle.setFillPattern(CellStyle.SOLID_前台);
fieldChangedStyle.setWrapText(true);
fieldDeletedStyle=workbook.createCellStyle();
fieldDeletedStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
fieldDeletedStyle.setFillPattern(CellStyle.SOLID_前台);
fieldDeletedStyle.setWrapText(true);
fieldUnchangedStyle=workbook.createCellStyle();
fieldUnchangedStyle.setWrapText(true);
}
public void writeHeader()引发IOException
{
用于(工作表下一步:工作表)
{
行r=next.getSheet().createRow(行计数器);
对于(int i=0;i 0)
{
CoverArt CoverArt=song.getcovertars().get(0);
value=coverart.getCoverImage().getWidth()+“x”+coverart.getCoverImage().getHeight();
c、 setCellValue(值);
}
}
其他的
{
value=song.getFieldValueOrEmptyString(songFieldName.getSongFieldKey())。替换('\u0000','\n');
c、 setCellStyle(fieldUnchangedStyle);
c、 setCellValue(值);
}
}
sfncw.setColumnWidthFromValue(值);
}
public void finish()引发IOException
{
用于(工作表下一步:工作表)
{
SXSSFSheet sheet=(SXSSFSheet)next.getSheet();
对于(int i=0;i最大列宽?最大列宽:columnWidth;
sheet.setColumnWidth(i,columnWidth*COL_WIDTH_乘数);
}
}
练习册。写作(fos);
fos.close();
workbook.dispose();
}
}

这应该可以完成您所追求的工作:


当轮子已经存在时,再发明轮子是没有意义的:)。希望这有帮助

刚刚发现xlsx格式只是一系列压缩成单个zip文件的Xml文件。因此,如果我尝试在Excel中为工作表手动创建一个表,保存更改,重命名为zip并解压缩,发现它创建了一个与xl/worksheets/sheet1.xml配套的xl/tables/table1.xml

它包括以下内容

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" id="1" name="Table1" displayName="Table1" ref="A1:M13" totalsRowShown="0" headerRowDxfId="0" dataDxfId="1">
    <autoFilter ref="A1:M13"/><tableColumns count="13">
        <tableColumn id="1" name="Filename"/>
        <tableColumn id="2" name="Artist" dataDxfId="12"/>
        <tableColumn id="3" name="Disc No" dataDxfId="11"/>
        <tableColumn id="4" name="Track No" dataDxfId="10"/>
        <tableColumn id="5" name="Single Disc TrackNo" dataDxfId="9"/>
        <tableColumn id="6" name="Title" dataDxfId="8"/>
        <tableColumn id="7" name="Album Artist" dataDxfId="7"/>
        <tableColumn id="8" name="Album" dataDxfId="6"/>
        <tableColumn id="9" name="Artwork"/>
        <tableColumn id="10" name="Year" dataDxfId="5"/>
        <tableColumn id="11" name="Original Release Year" dataDxfId="4"/>
        <tableColumn id="12" name="Genre" dataDxfId="3"/>
        <tableColumn id="13" name="Grouping" dataDxfId="2"/>
        </tableColumns>
        <tableStyleInfo name="TableStyleMedium2" showFirstColumn="0" showLastColumn="0" showRowStripes="1" showColumnStripes="0"/>
</table>

Sheet1.xml包含

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet 
    xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
    <dimension ref="A1:M13"/>
    <sheetViews>
        <sheetView tabSelected="1" workbookViewId="0">
            <selection activeCell="A6" sqref="A6"/>
        </sheetView>
    </sheetViews>
    <sheetFormatPr defaultRowHeight="15" x14ac:dyDescent="0.25"/>
        <cols>
            <col min="1" max="1" width="69" customWidth="1"/>
            <col min="2" max="2" width="20" customWidth="1"/>
            <col min="3" max="3" width="12" customWidth="1"/>
            <col min="4" max="4" width="13" customWidth="1"/>
            <col min="5" max="5" width="24" customWidth="1"/>
            <col min="6" max="6" width="32" customWidth="1"/>
            <col min="7" max="7" width="18" customWidth="1"/>
            <col min="8" max="8" width="23" customWidth="1"/>
            <col min="9" max="9" width="13" customWidth="1"/>
            <col min="10" max="10" width="9" customWidth="1"/>
            <col min="11" max="11" width="26" customWidth="1"/>
            <col min="12" max="12" width="36" customWidth="1"/>
            <col min="13" max="13" width="13" customWidth="1"/>
        </cols>
    <sheetData>
        <row r="1" spans="1:13" x14ac:dyDescent="0.25">
            <c r="A1" s="1" t="s"><v>0</v></c>
            <c r="B1" s="1" t="s"><v>1</v></c>
            <c r="C1" s="1" t="s"><v>2</v></c>
            ................................
            <c r="M13" s="3" t="s"><v>22</v></c>
        </row>
    </sheetData>
    <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
    <tableParts count="1"><tablePart r:id="rId1"/>
    </tableParts>