实现Excel小计功能

发布于 2025-01-03 19:13:48 字数 472 浏览 1 评论 0原文

Excel 通过菜单数据 -> 提供小计选项。 大纲 -> 小计。它会自动创建子和以及折叠数据的可能性。下图演示了该操作如何转换工作表。

在此处输入图像描述

这正是我需要通过 POI 执行的操作。我知道如何在单元格中设置小计函数,这样我就可以自己计算中间和。但是如何在左边框上启用这种折叠功能呢?

我意识到有 groupRow() 方法,但这些嵌套组无法正常工作。如果我使用以下代码,我只会得到两组。一大(1-7)和(1-3)。组 (5-7) 丢失,并且更改调用顺序没有任何效果。

sheet.groupRow(1, 7);
sheet.groupRow(1, 3);
sheet.groupRow(5, 7);

Excel provides the Subtotal option from the Menu Data -> Outline -> Subtotal. It creates automatically the sub-sums and the possibility to fold the data. The image below demonstrates how the action transforms the sheet.

enter image description here

And this is exactly what I need to do via POI. I know how to set a subtotal function into a cell so I could calculate the intermediate sums by myself. But how do I enable this folding on the left border?

I realised there is the groupRow() method but those nested groups doesn't work like they should. If I use the following code I only get two groups. One large (1-7) and (1-3). The group (5-7) is missing and changing the order of the calls has no effect.

sheet.groupRow(1, 7);
sheet.groupRow(1, 3);
sheet.groupRow(5, 7);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

挥剑断情 2025-01-10 19:13:48

我使用的是 POI 的一个相当旧的版本,但这就是我的做法:
我还需要多个嵌套组,因此我有一个存储缩进级别的行模型(它是一棵树,因此缩进是隐式的)。我与访问者一起遍历模型以获取组的开始行号和结束行号。然后调用 HSSFSheet。随后为每个组进行 groupRow 。如果我没记错的话,群组通话的顺序很重要。

I use a quite old verion of POI but this is how I did it:
I also needed multiple nested groups so I had a model for the rows where the indent level was stored as well (it was a tree so the indent was implicit). I traversed the model with a visitor to get the group start and end row numbers. Then called HSSFSheet.groupRow subsequently for each group. If I remember correctly, the order of the group calls is important.

败给现实 2025-01-10 19:13:48

我认为这正是您正在寻找的:

http://www.mysamplecode.com/2011/10/apache-poi-excel-row-group-collapse.html

如果您使用您可以使用 subtotal(9,) 而不是 sum() 执行嵌套组,因为小计会忽略其范围内包含小计的单元格

I think this is exactly what you are looking for:

http://www.mysamplecode.com/2011/10/apache-poi-excel-row-group-collapse.html

if you use subtotal(9,<range>) instead of sum(<range>), you can perform nested groups as subtotal ignores cell with subtotal in its range

小鸟爱天空丶 2025-01-10 19:13:48

使用以下库,您可以计算所需的小计。

<dependency>
  <groupId>com.github.bld-commons.excel</groupId>
  <artifactId>generator-excel</artifactId>
  <version>3.1.1</version>
</dependency>

该库是 apache poi 的包装器。
在源代码下方:

  1. 您创建一个代表表行的类。
  2. package bld.generator.report.junit.entity;
    
    import org.apache.poi.ss.usermodel.DataConsolidateFunction;
    import org.apache.poi.ss.usermodel.HorizontalAlignment;
    
    import bld.generator.report.excel.RowSheet;
    import bld.generator.report.excel.annotation.ExcelCellLayout;
    import bld.generator.report.excel.annotation.ExcelColumn;
    import bld.generator.report.excel.annotation.ExcelFont;
    import bld.generator.report.excel.annotation.ExcelSubtotal;
    import bld.generator.report.excel.annotation.ExcelSubtotals;
    
    @ExcelSubtotals(labelTotalGroup = "Total",endLabel = "total")
    public class SalaryRow implements RowSheet {
    
        @ExcelColumn(columnName = "Name", indexColumn = 0)
        @ExcelCellLayout
        private String name;
        @ExcelColumn(columnName = "Amount", indexColumn = 1)
        @ExcelCellLayout(horizontalAlignment = HorizontalAlignment.RIGHT)
        @ExcelSubtotal(dataConsolidateFunction = DataConsolidateFunction.SUM,excelCellLayout = @ExcelCellLayout(horizontalAlignment = HorizontalAlignment.RIGHT,font=@ExcelFont(bold = true)))
        private Double amount;
        
        public SalaryRow() {
            super();
        }
        public SalaryRow(String name, Double amount) {
            super();
            this.name = name;
            this.amount = amount;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Double getAmount() {
            return amount;
        }
        public void setAmount(Double amount) {
            this.amount = amount;
        }
        
    }
    
  3. 您创建一个代表该工作表的类。
  4. package bld.generator.report.junit.entity;
    
    import javax.validation.constraints.Size;
    
    import bld.generator.report.excel.SheetData;
    import bld.generator.report.excel.annotation.ExcelHeaderLayout;
    import bld.generator.report.excel.annotation.ExcelMarginSheet;
    import bld.generator.report.excel.annotation.ExcelSheetLayout;
    @ExcelSheetLayout
    @ExcelHeaderLayout
    @ExcelMarginSheet(bottom = 1.5,left = 1.5,right = 1.5,top = 1.5)
    public class SalarySheet extends SheetData<SalaryRow> {
    
        public SalarySheet(@Size(max = 31) String sheetName) {
            super(sheetName);
        }
    
    }
    
  5. 类测试
  6. package bld.generator.report.junit;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    import bld.generator.report.excel.BaseSheet;
    import bld.generator.report.excel.GenerateExcel;
    import bld.generator.report.excel.data.ReportExcel;
    import bld.generator.report.junit.entity.SalaryRow;
    import bld.generator.report.junit.entity.SalarySheet;
    import bld.generator.report.utils.ExcelUtils;
    
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @ConfigurationProperties
    @ComponentScan(basePackages = {"bld.generator","bld.read"})
    @EnableTransactionManagement
    public class SalaryTest {
    
        private static final String PATH_FILE = "/mnt/report/";
    
        @Autowired
        private GenerateExcel generateExcel;
    
        /**
         * Sets the up.
         *
         * @throws Exception the exception
         */
        @Before
        public void setUp() throws Exception {
        }
    
        @Test
        public void testSalary() throws Exception {
            List<BaseSheet> listBaseSheet = new ArrayList<>();
            SalarySheet salarySheet=new SalarySheet("salary");
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            listBaseSheet.add(salarySheet);
            
            ReportExcel report=new ReportExcel("test", listBaseSheet);
            
            byte[] byteReport = this.generateExcel.createFileXlsx(report);
            ExcelUtils.writeToFile(PATH_FILE,report.getTitle(), ".xlsx", byteReport);
            
        }
        
        
    
    }
    

在github上的项目链接下面:

低于结果。
在此处输入图片说明

With following library you can to calculate the subtotals that you want

<dependency>
  <groupId>com.github.bld-commons.excel</groupId>
  <artifactId>generator-excel</artifactId>
  <version>3.1.1</version>
</dependency>

This library is wrapper of apache poi.
Below the source code:

  1. You create a class that represents the row of the table.
  2. package bld.generator.report.junit.entity;
    
    import org.apache.poi.ss.usermodel.DataConsolidateFunction;
    import org.apache.poi.ss.usermodel.HorizontalAlignment;
    
    import bld.generator.report.excel.RowSheet;
    import bld.generator.report.excel.annotation.ExcelCellLayout;
    import bld.generator.report.excel.annotation.ExcelColumn;
    import bld.generator.report.excel.annotation.ExcelFont;
    import bld.generator.report.excel.annotation.ExcelSubtotal;
    import bld.generator.report.excel.annotation.ExcelSubtotals;
    
    @ExcelSubtotals(labelTotalGroup = "Total",endLabel = "total")
    public class SalaryRow implements RowSheet {
    
        @ExcelColumn(columnName = "Name", indexColumn = 0)
        @ExcelCellLayout
        private String name;
        @ExcelColumn(columnName = "Amount", indexColumn = 1)
        @ExcelCellLayout(horizontalAlignment = HorizontalAlignment.RIGHT)
        @ExcelSubtotal(dataConsolidateFunction = DataConsolidateFunction.SUM,excelCellLayout = @ExcelCellLayout(horizontalAlignment = HorizontalAlignment.RIGHT,font=@ExcelFont(bold = true)))
        private Double amount;
        
        public SalaryRow() {
            super();
        }
        public SalaryRow(String name, Double amount) {
            super();
            this.name = name;
            this.amount = amount;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Double getAmount() {
            return amount;
        }
        public void setAmount(Double amount) {
            this.amount = amount;
        }
        
    }
    
  3. You create a class that represents the sheet.
  4. package bld.generator.report.junit.entity;
    
    import javax.validation.constraints.Size;
    
    import bld.generator.report.excel.SheetData;
    import bld.generator.report.excel.annotation.ExcelHeaderLayout;
    import bld.generator.report.excel.annotation.ExcelMarginSheet;
    import bld.generator.report.excel.annotation.ExcelSheetLayout;
    @ExcelSheetLayout
    @ExcelHeaderLayout
    @ExcelMarginSheet(bottom = 1.5,left = 1.5,right = 1.5,top = 1.5)
    public class SalarySheet extends SheetData<SalaryRow> {
    
        public SalarySheet(@Size(max = 31) String sheetName) {
            super(sheetName);
        }
    
    }
    
  5. Class test
  6. package bld.generator.report.junit;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    import bld.generator.report.excel.BaseSheet;
    import bld.generator.report.excel.GenerateExcel;
    import bld.generator.report.excel.data.ReportExcel;
    import bld.generator.report.junit.entity.SalaryRow;
    import bld.generator.report.junit.entity.SalarySheet;
    import bld.generator.report.utils.ExcelUtils;
    
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @ConfigurationProperties
    @ComponentScan(basePackages = {"bld.generator","bld.read"})
    @EnableTransactionManagement
    public class SalaryTest {
    
        private static final String PATH_FILE = "/mnt/report/";
    
        @Autowired
        private GenerateExcel generateExcel;
    
        /**
         * Sets the up.
         *
         * @throws Exception the exception
         */
        @Before
        public void setUp() throws Exception {
        }
    
        @Test
        public void testSalary() throws Exception {
            List<BaseSheet> listBaseSheet = new ArrayList<>();
            SalarySheet salarySheet=new SalarySheet("salary");
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("a",2.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            salarySheet.getListRowSheet().add(new SalaryRow("c",1.0));
            listBaseSheet.add(salarySheet);
            
            ReportExcel report=new ReportExcel("test", listBaseSheet);
            
            byte[] byteReport = this.generateExcel.createFileXlsx(report);
            ExcelUtils.writeToFile(PATH_FILE,report.getTitle(), ".xlsx", byteReport);
            
        }
        
        
    
    }
    

Below the link of the project on github:

Below the result.
enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文