easyexcel Excel 加密处理文件类型问题

nuypyhwy  于 9个月前  发布在  其他
关注(0)|答案(5)|浏览(117)

使用 EasyExcel 写加密后 xlsx 文档,并设置密码。读取的时候,不能设置 excelType 为 xlsx,否则报错;

代码复现

  1. final List<DataVo> dataList = new ArrayList<>();
  2. try (final FileOutputStream output = new FileOutputStream(new File("file.xlsx"))) {
  3. try (final ExcelWriter excelWriter =
  4. EasyExcel.write(output, DataVo.class)
  5. .excelType(ExcelTypeEnum.XLSX)
  6. .charset(StandardCharsets.UTF_8)
  7. .password("password")
  8. .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
  9. .build()) {
  10. WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
  11. excelWriter.write(dataList, writeSheet);
  12. excelWriter.finish();
  13. }
  14. }
  15. EasyExcel.read(
  16. new FileInputStream("file.xlsx"),
  17. DataVo.class,
  18. new FileLisnter()
  19. )
  20. .password("password")
  21. .excelType(ExcelTypeEnum.XLSX)
  22. .sheet(0)
  23. .doRead();

目前了解到的细节

  1. 不设置 excelType 时,easyexcel 默认 ExcelTypeEnum.valueOf 会返回 xls.;
  2. 使用 Microsoft Office 使用密码能正常打 file.xlsx ,并没有提示文件格式问题;
vawmfj5a

vawmfj5a1#

第一个方法,可以试试在设置excelType后设置密码

qyuhtwio

qyuhtwio2#

第二个方法,就是提前对excel文件解密,然后解密的数据使用EasyExcel读,相关用例如下

  1. import org.junit.jupiter.api.Test;
  2. public class MyTest {
  3. @Test
  4. public void test() {
  5. final List<DemoData> dataList = new ArrayList<>();
  6. DemoData demoData = new DemoData();
  7. demoData.setId(System.currentTimeMillis());
  8. demoData.setString("你好");
  9. demoData.setDate(new Date());
  10. demoData.setDoubleData(23.0);
  11. dataList.add(demoData);
  12. try (final FileOutputStream output = new FileOutputStream("file.xlsx")) {
  13. try (final ExcelWriter excelWriter =
  14. EasyExcel.write(output, DemoData.class)
  15. .excelType(ExcelTypeEnum.XLSX)
  16. .charset(StandardCharsets.UTF_8)
  17. .password("password")
  18. .build()) {
  19. WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
  20. excelWriter.write(dataList, writeSheet);
  21. excelWriter.finish();
  22. }
  23. } catch (IOException e) {
  24. throw new RuntimeException(e);
  25. }
  26. FileInputStream fis = new FileInputStream("file.xlsx");
  27. POIFSFileSystem fs = new POIFSFileSystem(fis);
  28. EncryptionInfo info = new EncryptionInfo(fs);
  29. Decryptor decryptor = Decryptor.getInstance(info);
  30. decryptor.verifyPassword("password");
  31. InputStream dataStream = decryptor.getDataStream(fs);
  32. EasyExcel.read(dataStream)
  33. // .password("password")
  34. .excelType(ExcelTypeEnum.XLSX)
  35. .head(DemoData.class)
  36. .registerReadListener(
  37. new ReadListener<DemoData>() {
  38. @Override
  39. public void invoke(DemoData data, AnalysisContext context) {
  40. System.out.println(data);
  41. }
  42. @Override
  43. public void doAfterAllAnalysed(AnalysisContext context) {
  44. }
  45. }
  46. )
  47. .sheet()
  48. .doRead();
  49. }
  50. }```
展开查看全部
im9ewurl

im9ewurl3#

第一个方法,可以试试在设置excelType后设置密码

这个方法没用

wbgh16ku

wbgh16ku4#

第二个方法,就是提前对excel文件解密,然后解密的数据使用EasyExcel读,相关用例如下

  1. import org.junit.jupiter.api.Test;
  2. public class MyTest {
  3. @Test
  4. public void test() {
  5. final List<DemoData> dataList = new ArrayList<>();
  6. DemoData demoData = new DemoData();
  7. demoData.setId(System.currentTimeMillis());
  8. demoData.setString("你好");
  9. demoData.setDate(new Date());
  10. demoData.setDoubleData(23.0);
  11. dataList.add(demoData);
  12. try (final FileOutputStream output = new FileOutputStream("file.xlsx")) {
  13. try (final ExcelWriter excelWriter =
  14. EasyExcel.write(output, DemoData.class)
  15. .excelType(ExcelTypeEnum.XLSX)
  16. .charset(StandardCharsets.UTF_8)
  17. .password("password")
  18. .build()) {
  19. WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
  20. excelWriter.write(dataList, writeSheet);
  21. excelWriter.finish();
  22. }
  23. } catch (IOException e) {
  24. throw new RuntimeException(e);
  25. }
  26. FileInputStream fis = new FileInputStream("file.xlsx");
  27. POIFSFileSystem fs = new POIFSFileSystem(fis);
  28. EncryptionInfo info = new EncryptionInfo(fs);
  29. Decryptor decryptor = Decryptor.getInstance(info);
  30. decryptor.verifyPassword("password");
  31. InputStream dataStream = decryptor.getDataStream(fs);
  32. EasyExcel.read(dataStream)
  33. // .password("password")
  34. .excelType(ExcelTypeEnum.XLSX)
  35. .head(DemoData.class)
  36. .registerReadListener(
  37. new ReadListener<DemoData>() {
  38. @Override
  39. public void invoke(DemoData data, AnalysisContext context) {
  40. System.out.println(data);
  41. }
  42. @Override
  43. public void doAfterAllAnalysed(AnalysisContext context) {
  44. }
  45. }
  46. )
  47. .sheet()
  48. .doRead();
  49. }
  50. }```

这个建议封装到 easyexcel 内部,自动识别是否是加密文档。如果是,直接提示需要密码即可。

展开查看全部
2j4z5cfb

2j4z5cfb5#

这个bug现在我在尝试修复,目前能给出的解决办法就是这样,这个内部是实现了这个解密逻辑的,但是不知道什么原因没有生效,导致没有解密成功,进而影响了解析

相关问题