c# - NPOI 在 MemoryStream 中写入 0 字节

标签 c# npoi

我需要将报告保存到MemoryStream,所以我执行下一步:

byte[] result = new byte[0];

using (var stream = new MemoryStream())
{
    XlsxReport.BuildTaskReport(stream);
    result = stream.ToArray();
}

在我的 XlsxReport 类下面:

public sealed class XlsxReport
{
    public const string FontName = "Times New Roman";
    private const int FontSize = 14;

    private readonly IWorkbook workbook;
    // Fonts
    private readonly IFont boldFont;
    private readonly IFont defaultFont;
    // Styles
    private readonly ICellStyle cbStyle;
    private readonly ICellStyle simpleStyle;
    private readonly ICellStyle cdStyle;
    private readonly ICellStyle ldStyle;
    // Sheet
    private readonly ISheet sheet;
    private readonly int rows, columns;

    private XlsxReport(int rows, int columns)
    {
        this.rows = rows;
        this.columns = columns;
        workbook = new XSSFWorkbook();
        // Prepare fonts
        boldFont = workbook.CreateFont();
        defaultFont = workbook.CreateFont();
        boldFont.FontHeightInPoints = FontSize;
        defaultFont.FontHeightInPoints = FontSize;
        boldFont.FontName = FontName;
        defaultFont.FontName = FontName;
        boldFont.Boldweight = (short)FontBoldWeight.Bold;
        // Prepare styles
        cbStyle = CreateCellStyle(boldFont);
        simpleStyle = CreateCellStyle(defaultFont, HorizontalAlignment.Justify);
        cdStyle = CreateCellStyle(defaultFont, HorizontalAlignment.Center, VerticalAlignment.Center, true, false);
        ldStyle = CreateCellStyle(defaultFont, HorizontalAlignment.Left, VerticalAlignment.Center, true, false);
        // Initialize a sheet
        sheet = workbook.CreateSheet(Headers.Page + " 1");
        CreateSheet(sheet, rows, columns, cdStyle);
    }

    private ICellStyle CreateCellStyle(IFont font, HorizontalAlignment horizontalAlignment = HorizontalAlignment.Center, 
        VerticalAlignment verticalAlignment = VerticalAlignment.Center, bool hasBorder = true, bool wrapText = true)
    {
        var style = workbook.CreateCellStyle();
        style.SetFont(font);
        style.Alignment = horizontalAlignment;
        style.VerticalAlignment = verticalAlignment;
        style.WrapText = wrapText;

        if (hasBorder)
        {
            SetBorder(style);
        }

        return style;
    }

    private void BuildMainHeader()
    {
        // Prepare styles
        var titleStyle = CreateCellStyle(boldFont, HorizontalAlignment.Center, VerticalAlignment.Center, false, false);
        var stampStyle = CreateCellStyle(defaultFont, HorizontalAlignment.Center, VerticalAlignment.Center, false, false);
        // Create a title
        GetCell(sheet.GetRow(0), 0, Headers.Report, titleStyle);
        // Create a timestamp
        GetCell(sheet.GetRow(2), 0, DateTime.Today.ToDateStr(), stampStyle);
        // Set regions
        var titleRegion = new CellRangeAddress(0, 0, 0, columns - 1);
        var stampRegion = new CellRangeAddress(2, 2, 0, columns - 1);
        sheet.AddMergedRegion(titleRegion);
        sheet.AddMergedRegion(stampRegion);
    }

    private void SetBorder(ICellStyle style)
    {
        style.BorderTop = BorderStyle.Medium;
        style.BorderBottom = BorderStyle.Medium;
        style.BorderLeft = BorderStyle.Medium;
        style.BorderRight = BorderStyle.Medium;
    }

    private ICell GetCell(IRow row, int index, string value, ICellStyle style)
    {
        var cell = row.GetCell(index);
        cell.SetCellValue(value);
        cell.CellStyle = style;
        cell.SetCellType(CellType.String);
        return cell;
    }

    private void SetBorder(CellRangeAddress region, ISheet sheet, IWorkbook wb)
    {
        RegionUtil.SetBorderBottom(2, region, sheet, wb);
        RegionUtil.SetBorderTop(2, region, sheet, wb);
        RegionUtil.SetBorderLeft(2, region, sheet, wb);
        RegionUtil.SetBorderRight(2, region, sheet, wb);
    }

    private void CreateSheet(ISheet sheet, int rows, int columns, ICellStyle style)
    {
        for (int i = 0; i < rows; ++i)
        {
            var row = sheet.CreateRow(i);

            for (int j = 0; j < columns; ++j)
            {
                var cell = row.CreateCell(j);

                if (i > 3) { cell.CellStyle = style; }
            }
        }
    }

    private void AutoSizeColumns()
    {
        for (int i = 0; i < columns; ++i)
        {
            sheet.AutoSizeColumn(i);
        }
    }

    public static void BuildTaskReport(Stream stream)
    {
        var report = new XlsxReport(5 + Count * 6, 6);
        report.BuildMainHeader();
        var sheet = report.sheet;
        // Set cell regions
        var head = report.sheet.GetRow(4);
        report.GetCell(head, 0, Headers.OrderNumber, report.cbStyle);
        report.GetCell(head, 1, Headers.TaskName, report.cbStyle);
        report.GetCell(head, 2, Headers.DateCreate, report.cbStyle);
        report.GetCell(head, 3, Headers.DateEnd, report.cbStyle);
        report.GetCell(head, 4, Headers.Priority, report.cbStyle);
        report.GetCell(head, 5, Headers.Status, report.cbStyle);
        ////////////////////////////////////////////////////////
        // Many lines to fill rows
        ////////////////////////////////////////////////////////
        // Resize columns
        report.AutoSizeColumns();
        // Save changes
        report.workbook.Write(stream);
        stream.Flush();
    }
}

但是在using block 之后我的结果仍然是0字节。我已在调试器中检查了我的报告生成器:IWorkbook 包含一个工作表,该工作表包含行,一切看起来都正确,似乎没有任何异常。
有什么问题吗?在我将代码移至 XlsxReport 类之前它就可以工作。

最佳答案

我今天也遇到了同样的问题。问题是我将 SharpZipLib 库从 0.86.* 更新到 1.0.*。它停止工作,或者至少应用程序开始将 0 字节放入流中。当我将此库降级回 0.86.* 时,一切都开始按预期再次工作。

关于c# - NPOI 在 MemoryStream 中写入 0 字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52432909/

相关文章:

c# - CQRS:类冗余并将 DTO 传递给域

c# - 如何使用 NPOI 库 c# 在 Excel 工作表中生成折线图和数据

c# - 如何知道使用 Entity Framework 4.1 的 asp.net MVC3 应用程序当前打开了多少个连接

c# - 删除验证消息名称中的集合索引

C# 和 NPOI 无法读取数字和字符串值

c# - 如何一次更改多个单元格的边框样式。非营利组织

excel - EPPlus v4 Worksheet.InsertRow >1024 错误

c# - 如何重新计算单元格的公式?

c# - 在 Identity Server 4 中添加自定义用户注册页面

c# - 如何将表达式 Func<T, object[]> 转换为 Func<T, object>