Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Region is very slow #293

Open
jhd147350 opened this issue Feb 2, 2024 · 2 comments
Open

Merge Region is very slow #293

jhd147350 opened this issue Feb 2, 2024 · 2 comments
Assignees
Labels
bug Something isn't working mergecells jx:mergeCells

Comments

@jhd147350
Copy link

jhd147350 commented Feb 2, 2024

I found the code below is very slow, and i don't know how to handle it.

protected final void findAndRemoveExistingCellRegion(CellRef cellRef) {
/////
}

the xlsx file looks like:

image

my test code:

import org.junit.jupiter.api.Test;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;

import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExcelTest {

    public static int COUNT = 1000;

    /**
     * if the template file has mergedRegions,it is really slow.
     * And will be slower and slower.
     */
    @Test
    public void slowTest() {
        List<Map<String, String>> mapList = new ArrayList<>();
        for (int i = 0; i < COUNT; i++) {
            Map<String, String> map = new HashMap<>();
            map.put("mergeA", "mergeA" + i);
            map.put("mergeB", "mergeB" + i);
            map.put("mergeC", "mergeC" + i);
            map.put("d", "d" + i);
            map.put("e", "e" + i);
            mapList.add(map);
        }

        HashMap<String, Object> map = new HashMap<>();
        map.put("rowList", mapList);
        byte[] bytes = getBytesFromTemplate(map, "ExcelTemplateSlow.xlsx");
        saveBytesToLocalFile(bytes, "ExcelExportSlow.xlsx");
    }

    /**
     * It will be normal when there is no mergedRegions.
     */
    @Test
    public void fastTest() {
        List<Map<String, String>> mapList = new ArrayList<>();
        for (int i = 0; i < COUNT; i++) {
            Map<String, String> map = new HashMap<>();
            map.put("a", "a" + i);
            map.put("b", "b" + i);
            map.put("c", "c" + i);
            map.put("d", "d" + i);
            map.put("e", "e" + i);
            mapList.add(map);
        }

        HashMap<String, Object> map = new HashMap<>();
        map.put("rowList", mapList);
        byte[] bytes = getBytesFromTemplate(map, "ExcelTemplateFast.xlsx");
        saveBytesToLocalFile(bytes, "ExcelExportFast.xlsx");
    }

    static public void saveBytesToLocalFile(byte[] bytes, String filename) {
        FileOutputStream fos = null;
        try {
            String filePath = "ExcelTemp";
            File path = new File(filePath);
            if (!path.exists() && !path.isDirectory()) {
                path.mkdir();
            }
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss-SSS");
            filename = now.format(dtf) + filename;

            fos = new FileOutputStream(filePath + "/" + filename);
            fos.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static public byte[] getBytesFromTemplate(Map<String, Object> map, String templateFileName) {
        try {
            InputStream is = ExcelTest.class.getClassLoader().getResourceAsStream(templateFileName);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            Context context = new Context(map);
            JxlsHelper.getInstance().processTemplate(is, os, context);
            if (is != null) {
                is.close();
            }
            return os.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "error".getBytes();
    }

}

you can clone the test demo from https://github.com/jhd147350/jxls-test

@jhd147350 jhd147350 added the bug Something isn't working label Feb 2, 2024
@SoltauFintel
Copy link
Member

I can confirm that it is reproducible and is slow. PoiTransformer.findAndRemoveExistingCellRegion is called 1000 times and the loop interior is called 4.5 million times. If this can be optimized, we should only do this in master (3.x). -> leonate

@gastendonk gastendonk removed the jxls-2 label Feb 29, 2024
@SoltauFintel SoltauFintel added the mergecells jx:mergeCells label Feb 29, 2024
@ganggangde123
Copy link

I can confirm that it is reproducible and is slow. PoiTransformer.findAndRemoveExistingCellRegion is called 1000 times and the loop interior is called 4.5 million times. If this can be optimized, we should only do this in master (3.x). -> leonate

please quickly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working mergecells jx:mergeCells
Projects
None yet
Development

No branches or pull requests

5 participants