AutoExcel - Wonderful Excel Import and Export Tool

GitHub | Blog | 中文 | English

Why AutoExcel?

Excel import and export is very common in software development, as long as you are a programmer, you have met. I believe that many people will choose to use Apache POI to complete this work like me. While feeling the power of POI, my team also encountered the following problems:

  1. Directly use POI to operate Excel will generate a lot of hard code, you will hardly write row index and column index in the code.
  2. A large number of non-reusable format control codes, such as background color, alignment, cell style, etc.
  3. The implementation consultant clearly provided a ready-made template, but had to develop the code to implement it again, resulting in low development efficiency.
  4. Development resources have to be used when the template is adjusted.
  5. Simple export also requires specific code.

AutoExcel solves the above problems. It is very simple and only requires a small amount of code to complete complex import and export. When using it, programmers have no sense of import and export, that is, there is no need to directly manipulate POI. At the same time, the implementation consultant provides Excel is the import and export template, unless new data sources or fields are added, the template update does not need to use development resources.

AutoExcel does not over-encapsulate the POI, but makes full use of Excel's own feature-the name manager, through some tricks, the cell and the data source are mapped, thereby decoupling the programmer and the POI, and avoid hard code, so that import and export work becomes enjoyable and no longer boring.

Function preview

Before export After export
image
image
image
image
image
image
image
image

To achieve the above export, you only need to write the following small amount of code (you need additional code to prepare the data source, for example, from the database)

List<TemplateExportPara> paras = new ArrayList<>();
paras.add(new TemplateExportPara("BusinessUnit", DataGenerator.genBusinessUnit()));
paras.add(new TemplateExportPara("Contract", DataGenerator.genContracts()));
paras.add(new TemplateExportPara("Project", DataGenerator.genProjects()));

List<Product> products = DataGenerator.genProducts();
TemplateExportPara para3 = new TemplateExportPara("Product", products);
para3.setInserted(true);
paras.add(para3);

TemplateExportPara para5 = new TemplateExportPara("Product2", products);
para5.setDataDirection(DataDirection.Right);
paras.add(para5);

ExcelSetting excelSetting = new ExcelSetting();
excelSetting.setRemovedSheets(Arrays.asList("will be removed"));

AutoExcel.save(this.getClass().getResource("/template/Common.xlsx").getPath(),
               this.getClass().getResource("/").getPath() + "ExportWithTemplate.xlsx",
               paras,
               excelSetting);

Know the template

To achieve the above export, you first need to complete the production of the template. Some report creation tools such as Microsoft’s RDL, you will make the export model in RDL, and then export the data to Excel in combination with the code. In this process, RDL only acts as an intermediary. It means that every time there is a new export task, an export model must be made first. In AutoExcel, Excel is the template. If your Excel comes from an implementation consultant, it is very likely that this Excel has already set the data format, cell style, etc. And it is waiting for you to fill in the data. In that case, why not use this Excel as our export template, what we have to do is just add our stuff to it.

Name manager

The name manager in Excel, a feature that is ignored by most people, has become a bridge between data sources and cells in AutoExcel. You can open the name manager by clicking the menu Formula->Name Manager. Each name corresponds to a specific location in Excel. It can be a region or a cell. Of course, here, the names we defined all point to cells. So it can be understood that the name manager is used to name cells. It is precisely because the cell has a name that we can automatically assign a value to the cell without the need for personalized code.

image

After defining the name for the cell, when you click on the cell again, you will find the name you just defined is displayed in the upper left corner.

image

In addition to adding new names in the name manager, there is another way that is more intuitive and faster. Click on the cell you want to name, then directly enter the name in the upper left corner, and finally press the Entry button. It is recommended to create names in this way.

image

Name rule

Because the cell name determines what kind of data and how to fill in, it must be named according to the following rules:

  1. DataSourceName.FieldName[.AggregateType], used to fill common fields or aggregate of common fields, e.g. product.SaleArea.sum
  2. DataSourceName.Formula.xxxx, used to fill the formula, e.g. product.Formula.1
  3. DataSourceName.RowNo, used to fill the row number, e.g. product.RowNo

All names are not case sensitive, the following will be introduced according to specific scenarios.

Export

Basic object

image

As shown in the figure, the name of each cell is indicated in the remarks, written in accordance with the rules of DataSourceName.FieldName

java code:

String templatePath = this.getClass().getResource("/template/Common.xlsx").getPath();
String outputPath = this.getClass().getResource("/").getPath() + "ExportWithTemplate.xlsx";
//DataGenerator.genBusinessUnit() used to generate demo data
TemplateExportPara para = new TemplateExportPara("BusinessUnit", DataGenerator.genBusinessUnit());
AutoExcel.save(templatePath, outputPath, para);

Single table

image

If you want to export a list of data, you only need to name it according to the writing rules of the base object. Of course, the export of list data is often more complicated than the basic object. For example, you may need a column of row numbers, but you don’t want to do special processing in the code. At this time, you can use DataSourceName.RowNo to hand over the work to AutoExcel to process. Note that RowNo is a built-in field. If this field is included in the data source, it will be overwritten.

There is also a very common situation, you have a cell with a formula in the table, such as: =E6+F6, you want the cell in the next row to be assigned the value =E7+F7. At this time, you should use DataSourceName.Formula.xxxx, you can use any formula you like, and AutoExcel will automatically fill it for you eventually. You can write whatever you want at the part of xxxx, as long as the name is unique. Formula is also a built-in field.

java code:

String templatePath = this.getClass().getResource("/template/Common.xlsx").getPath();
String outputPath = this.getClass().getResource("/").getPath() + "ExportWithTemplate.xlsx";
//DataGenerator.genContracts() used to generate demo data
TemplateExportPara para = new TemplateExportPara("Contract", DataGenerator.genContracts());
AutoExcel.save(templatePath, outputPath, para);

Multi-table

image

Export multiple tables in one Sheet. If you have such a requirement, please set the export parameter of the table that is not at the bottom in the background code to: setInserted(true). As shown in the figure above, the export parameter para corresponding to products should be set as follows: para.setInserted(true). You know, AutoExcel does not care about whether there is enough space for data export, it will only output continuously. So when your template space is not enough, you need to tell AutoExcel, and then AutoExcel will make enough space to hold your data before exporting.

A new naming rule is introduced here: DataSourceName.FieldName.AggregateType, used to total the specified fields. Currently, two aggregate types are supported: Sum and Avg.

java code:

String templatePath = this.getClass().getResource("/template/Common.xlsx").getPath();
String outputPath = this.getClass().getResource("/").getPath() + "ExportWithTemplate.xlsx";
List<TemplateExportPara> paras = new ArrayList<>();
//DataGenerator.genProjects() used to generate demo data
paras.add(new TemplateExportPara("Project", DataGenerator.genProjects()));

//DataGenerator.genProducts() used to generate demo data
TemplateExportPara para = new TemplateExportPara("Product", DataGenerator.genProducts());
para.setInserted(true);  //Need to set when the space is not enough in the template
paras.add(para);

AutoExcel.save(templatePath, outputPath, paras);

Fill data to the right

image

If you need to fill the data to the right instead of down, you just need to use setDataDirection(DataDirection.Right).

java code:

String templatePath = this.getClass().getResource("/template/Common.xlsx").getPath();
String outputPath = this.getClass().getResource("/").getPath() + "ExportWithTemplate.xlsx";
TemplateExportPara para = new TemplateExportPara("Product2", DataGenerator.genProducts());
para.setDataDirection(DataDirection.Right);  //Fill data to the right
AutoExcel.save(templatePath, outputPath, para);

Export directly

Export directly, that is, the export process does not require the use of templates, and is suitable for integration into the general export function of the back-end system. The code is very simple.

String outputPath = this.getClass().getResource("/").getPath() + "Export.xlsx";
DirectExportPara para = new DirectExportPara(DataGenerator.genProjects());
AutoExcel.save(outputPath, para);

effect:

image

Of course, you don't like this kind of title and title order, so you need to use FieldSetting to make your title readable and display in the order you like.

List<FieldSetting> fieldSettings = new ArrayList<FieldSetting>() {{
    add(new FieldSetting("projName", "Project Name"));
    add(new FieldSetting("basalArea", "Basal Area"));
    add(new FieldSetting("buildingArea", "Building Area"));
    add(new FieldSetting("insideArea", "Inside Area"));
    add(new FieldSetting("availableArea", "Available Area"));
    add(new FieldSetting("availablePrice", "Available Price"));
    add(new FieldSetting("availableAmount", "Available Amount"));
}};
String outputPath = this.getClass().getResource("/").getPath() + "Export.xlsx";
DirectExportPara para = new DirectExportPara(DataGenerator.genProjects(), "Projects", fieldSettings);
AutoExcel.save(outputPath, para);

final effect:

image

Custom action

AutoExcel is committed to dealing with general scenarios of import and export. If there is a personalized demand, you should take back the control of Workbook and perform personalized processing according to your needs. The save method provides two Consumers, of which actionAhead will be called before the export operation starts, and actionBehind will be called after the export is completed. You can use these two Consumers to add the functions you want.

String templatePath = this.getClass().getResource("/template/Common.xlsx").getPath();
String outputPath = this.getClass().getResource("/").getPath() + "ExportWithTemplate.xlsx";
List<TemplateExportPara> paras = new ArrayList<>();
paras.add(new TemplateExportPara("BusinessUnit", DataGenerator.genBusinessUnit()));
Consumer<Workbook> actionAhead = Workbook -> {
    //Do whatever you want
};        
Consumer<Workbook> actionBehind = workbook -> {
    //Do whatever you want
};
AutoExcel.save(templatePath, outputPath, paras, actionAhead, actionBehind);

Import

Compared with export, import has the following characteristics:

  1. Only one name rule is supported: DataSourceName.FieldName.

  2. The situation where there are multiple tables in one sheet is not currently supported.

  3. The default data reading direction (DataDirection) is null, that is to read the basic object. If you need to read the list, you need to specify the reading direction as Down. Right direction reading is not currently supported.

java code:

List<ImportPara> importParas = new ArrayList<ImportPara>() {{
    add(new ImportPara("BusinessUnit"));
    add(new ImportPara("Contract", DataDirection.Down));
    add(new ImportPara("Project", DataDirection.Down));
    //add(new ImportPara("Product", DataDirection.Down));  not supported currently
}};
String fileName = this.getClass().getResource("/").getPath() + "ExportWithTemplate.xlsx";
HashMap<String, List<HashMap<String, Object>>> datas = AutoExcel.read(fileName, importParas);

Run the sample code

Please go to the unit test to get the complete sample code.

GitHub

image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349