diff --git a/src/main/java/com/example/exam/exam/service/wpsexcel/WpsExcelUtils.java b/src/main/java/com/example/exam/exam/service/wpsexcel/WpsExcelUtils.java index 7ea5812..df613f0 100644 --- a/src/main/java/com/example/exam/exam/service/wpsexcel/WpsExcelUtils.java +++ b/src/main/java/com/example/exam/exam/service/wpsexcel/WpsExcelUtils.java @@ -1,918 +1,1109 @@ -package com.example.exam.exam.service.wpsexcel; - -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.DateUtil; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.apache.xmlbeans.XmlCursor; -import org.apache.xmlbeans.XmlObject; - -import javax.xml.namespace.QName; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -/** - * @author REN - */ -public class WpsExcelUtils { - - public static final String namespace = "declare namespace ns='http://schemas.openxmlformats.org/spreadsheetml/2006/main' "; - - public static final List> drawingSheetVOS = new ArrayList<>(); - - public static int dxfId = 0; - - - public static String getStringRandom() { - String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - Random random = new Random(); - StringBuilder sb = new StringBuilder(); - - // 生成指定长度的随机字符字符串 - for (int i = 0; i < 10; i++) { - int randomIndex = random.nextInt(characters.length()); - // 随机字符 - sb.append(characters.charAt(randomIndex)); - } - return sb.toString(); - } - - public static List wpsExcelInfo(String filePath) throws Exception { - List excelInfoReqVoList = new ArrayList<>(); - try (FileInputStream fis = new FileInputStream(filePath); - OPCPackage pkg = OPCPackage.open(fis); - XSSFWorkbook workbook = new XSSFWorkbook(pkg)) { - // 获取有多少个工作表 - int sheetNumber = workbook.getNumberOfSheets(); - String firstIdSheet = getStringRandom(); - for (int i = 0; i < sheetNumber; i++) { - String secondIdSheet = getStringRandom(); - // 获取工作表内容 - XSSFSheet sheetXss = workbook.getSheetAt(i); - // 获取工作表的XML对象 - XmlObject worksheetXml = sheetXss.getCTWorksheet(); - setWordInfo("Sheet" + sheetNumber + 1, "Sheet" + sheetNumber + 1, "sheet" + sheetNumber + 1 + ".xml", filePath, secondIdSheet, firstIdSheet, excelInfoReqVoList); - - // 开始查找指定得 单元格、范围、行、列、数据排序、数据透视表、表格、图标、页面、试图、属性 - String thirdIdC = getStringRandom(); - setWordInfo("单元格", "c", "c", filePath, thirdIdC, secondIdSheet, excelInfoReqVoList); - String thirdIdCC = getStringRandom(); - setWordInfo("范围", "cc", "cc", filePath, thirdIdCC, secondIdSheet, excelInfoReqVoList); - String thirdIdRow = getStringRandom(); - setWordInfo("行", "row", "row", filePath, thirdIdRow, secondIdSheet, excelInfoReqVoList); - String thirdIdCol = getStringRandom(); - setWordInfo("列", "cols", "cols", filePath, thirdIdCol, secondIdSheet, excelInfoReqVoList); +//package com.example.exam.exam.service.wpsexcel; +// +//import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +//import org.apache.poi.openxml4j.opc.OPCPackage; +//import org.apache.poi.ss.usermodel.Cell; +//import org.apache.poi.ss.usermodel.CellStyle; +//import org.apache.poi.ss.usermodel.DateUtil; +//import org.apache.poi.ss.usermodel.Row; +//import org.apache.poi.xssf.usermodel.XSSFSheet; +//import org.apache.poi.xssf.usermodel.XSSFWorkbook; +//import org.apache.xmlbeans.XmlCursor; +//import org.apache.xmlbeans.XmlObject; +// +//import javax.xml.namespace.QName; +//import java.io.FileInputStream; +//import java.io.IOException; +//import java.io.InputStream; +//import java.util.*; +//import java.util.regex.Matcher; +//import java.util.regex.Pattern; +//import java.util.zip.ZipEntry; +//import java.util.zip.ZipFile; +// +///** +// * @author REN +// */ +//public class WpsExcelUtils { +// +// public static final String namespace = "declare namespace ns='http://schemas.openxmlformats.org/spreadsheetml/2006/main' "; +// +// public static final List> drawingSheetVOS = new ArrayList<>(); +// +// public static int dxfId = 0; +// +// +// public static String getStringRandom() { +// String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +// Random random = new Random(); +// StringBuilder sb = new StringBuilder(); +// +// // 生成指定长度的随机字符字符串 +// for (int i = 0; i < 10; i++) { +// int randomIndex = random.nextInt(characters.length()); +// // 随机字符 +// sb.append(characters.charAt(randomIndex)); +// } +// return sb.toString(); +// } +// +// public static List wpsExcelInfo(String filePath) throws Exception { +// List excelInfoReqVoList = new ArrayList<>(); +// try (FileInputStream fis = new FileInputStream(filePath); +// OPCPackage pkg = OPCPackage.open(fis); +// XSSFWorkbook workbook = new XSSFWorkbook(pkg)) { +// // 获取有多少个工作表 +// int sheetNumber = workbook.getNumberOfSheets(); +// String firstIdSheet = getStringRandom(); +// for (int i = 0; i < sheetNumber; i++) { +// String secondIdSheet = getStringRandom(); +// // 获取工作表内容 +// XSSFSheet sheetXss = workbook.getSheetAt(i); +// // 获取工作表的XML对象 +// XmlObject worksheetXml = sheetXss.getCTWorksheet(); +// setWordInfo("Sheet" + sheetNumber + 1, "Sheet" + sheetNumber + 1, "sheet" + sheetNumber + 1 + ".xml", filePath, secondIdSheet, firstIdSheet, excelInfoReqVoList); +// +// // 开始查找指定得 单元格、范围、行、列、数据排序、数据透视表、表格、图标、页面、试图、属性 +// String thirdIdC = getStringRandom(); +// setWordInfo("单元格", "c", "c", filePath, thirdIdC, secondIdSheet, excelInfoReqVoList); +// String thirdIdCC = getStringRandom(); +// setWordInfo("范围", "cc", "cc", filePath, thirdIdCC, secondIdSheet, excelInfoReqVoList); +// String thirdIdRow = getStringRandom(); +// setWordInfo("行", "row", "row", filePath, thirdIdRow, secondIdSheet, excelInfoReqVoList); // String thirdIdCol = getStringRandom(); - // 判断是否存在图表 - setWordInfo("列", "cols", "cols", filePath, thirdIdCol, secondIdSheet, excelInfoReqVoList); - - System.out.println(worksheetXml.xmlText()); - } - } catch (IOException e) { - e.printStackTrace(); - } catch (InvalidFormatException e) { - throw new RuntimeException(e); - } - - - return excelInfoReqVoList; - } - public static void setWordInfo(String chineseName, String englishName, String selectName, String filePath, String id, String parentId, List excelInfoReqVos) throws Exception { - ExcelInfoReqVo excelInfos = new ExcelInfoReqVo(); - excelInfos.setName(chineseName); - excelInfos.setEnglishName(englishName); - excelInfos.setFilePath(filePath); - excelInfos.setId(id); - excelInfos.setSelectName(selectName); - excelInfos.setParentId(parentId); - excelInfoReqVos.add(excelInfos); - } - - - public static List wpsExcel(String filePath, String index) throws Exception { - // 获取共享字符串 - String[] sharedStrings = extractSharedStrings(filePath); - // 读取样式xml - XmlCursor styleXml = extractStyleXml(filePath); - // 作簿中的数据连接(Data Connections),即 Excel 与外部数据源(如数据库、Web 服务、其他文件等)的链接信息 - XmlCursor connectionsXml = extractConnectionsXml(filePath); - // 获取工作簿中的图表数据 -// List chartListXmls = extractChartXml(filePath); - getDrawingInfos(filePath); - // 单元格数据 - List xlsxInfoVos = new ArrayList<>(); - try (FileInputStream fis = new FileInputStream(filePath); - OPCPackage pkg = OPCPackage.open(fis); - XSSFWorkbook workbook = new XSSFWorkbook(pkg)) { - // 获取有多少个工作表 - int sheetNumber = workbook.getNumberOfSheets(); - for (int i = 0; i < sheetNumber; i++) { -// System.out.println("第 " + (i + 1) + " 个工作表"); - // 获取工作表内容 - XSSFSheet sheetXss = workbook.getSheetAt(i); - // 获取工作表的XML对象 - XmlObject worksheetXml = sheetXss.getCTWorksheet(); - // 读取条件格式,并转化条件 - XmlCursor conditionalFormatting = worksheetXml.newCursor(); - conditionalFormatting.selectPath(namespace + "//ns:conditionalFormatting"); - String sqref = ""; - String formula = ""; - boolean conditionalFormattingFlag = false; - if (conditionalFormatting.toNextSelection()) { - conditionalFormattingFlag = true; - // 使用了条件格式,作用范围 - XmlCursor sqrefXml = conditionalFormatting.getObject().newCursor(); - sqrefXml.selectPath(namespace + "./@sqref"); - if (sqrefXml.toNextSelection()) { - sqref = sqrefXml.getTextValue(); - } - // 查询条件 - XmlCursor cfRuleXml = conditionalFormatting.getObject().newCursor(); - cfRuleXml.selectPath(namespace + "./ns:cfRule"); - if (cfRuleXml.toNextSelection()){ - dxfId = Integer.parseInt(cfRuleXml.getAttributeText(new QName("dxfId"))); - XmlCursor formulaXml = cfRuleXml.getObject().newCursor(); - formulaXml.selectPath(namespace + "./ns:formula"); - if (formulaXml.toNextSelection()) { - formula = cfRuleXml.getTextValue(); - } - } - } - try (XmlCursor cursor = worksheetXml.newCursor()) { -// drawingXmlInfo(cursor, String.valueOf(i+1)); - // 查询所有 row 元素 - cursor.selectPath(namespace + "//ns:worksheet/ns:sheetData/ns:row"); - int rowIndex = 0; - while (cursor.toNextSelection()) { - // 行的参数 - XmlCursor rowXml = cursor.getObject().newCursor(); - addXlsxInfo(String.valueOf(i+1), "行高", "ns:row/@ht", rowXml.getAttributeText(new QName("ht")), "row", "行" + rowXml.getAttributeText(new QName("r")), "style", "样式", "r"+rowXml.getAttributeText(new QName("r")), xlsxInfoVos); - addXlsxInfo(String.valueOf(i+1), "行高", "ns:row/@ht", rowXml.getAttributeText(new QName("ht")), "row", "行" + rowXml.getAttributeText(new QName("r")),"style", "样式", "r"+rowXml.getAttributeText(new QName("r")), xlsxInfoVos); - - - try (XmlCursor rowCursor = rowXml.newCursor()) { - rowCursor.selectPath(namespace + "./ns:c"); - // 接着获取单元格 - int colIndex = 0; - while (rowCursor.toNextSelection()) { - // 判断是否使用了条件样式进行判断值 - boolean isConditionalFormatting = false; - if (conditionalFormattingFlag) { - // 进行拆分单元格 - // 1. 提取列字母(正则匹配 $K2 或 K2) - // 字符串替换 - String formulas = formula.replaceAll("\\$", "").split("=")[0]; - Pattern pattern = Pattern.compile("^[A-Za-z]+"); - Matcher matcher = pattern.matcher(formulas); - String colLetters = ""; - while (matcher.find()) { - colLetters = matcher.group(0); - } - int colIndexMatcher = columnLetterToNumber(colLetters); - // 读取指定单元格 - Row row = sheetXss.getRow(rowIndex); - if (row == null) { - break; - } - Cell cell = row.getCell(colIndexMatcher-1); - String value = getCellValue(cell); - // 获取对比值 - String compareValue = formula.split("=")[1].replace("\"", "");; - if (Objects.equals(value, compareValue)) { - isConditionalFormatting = true; - } - } - Row row = sheetXss.getRow(rowIndex); - if (row == null) { - break; - } - // 获取行属性 - Cell cell = row.getCell(colIndex); - if (row != null && cell != null) { - // 获取单元格 - String rowName = rowCursor.getAttributeText(new QName("r")); - // 获取style编号 - String styleId = rowCursor.getAttributeText(new QName("s")); - // 获取共享字符串 - String tName = rowCursor.getAttributeText(new QName("t")); - // 获取具体的值 - try (XmlCursor valueXml = rowCursor.getObject().newCursor()) { - String value = ""; - valueXml.selectPath(namespace + "./ns:v"); - if (valueXml.toNextSelection()) { - value = valueXml.getTextValue(); - } - // 如果是共享字符串 - if (tName != null && tName.equals("s")) { - value = sharedStrings[Integer.parseInt(value)]; - addXlsxInfo(String.valueOf(i+1), "单元格文本", "ns:celltext", value, "cell", "单元格", "text", "文本", rowName, xlsxInfoVos); - } else { - addXlsxInfo(String.valueOf(i+1), "单元格文本", "ns:celltext", value, "cell", "单元格", "text", "文本", rowName, xlsxInfoVos); - } - - valueXml.dispose(); - } - // 获取公式 - try (XmlCursor formulaXml = rowCursor.getObject().newCursor()) { - String value = ""; - formulaXml.selectPath(namespace + "./ns:f"); - if (formulaXml.toNextSelection()) { - value = formulaXml.getTextValue(); - addXlsxInfo(String.valueOf(i+1), "单元格公式", "ns:formula", value, "cell", "单元格", "text", "文本", rowName, xlsxInfoVos); - } - formulaXml.dispose(); - } - // 获取单元格的格式 - CellStyle cellStyle = cell.getCellStyle(); -// System.out.println(rowIndex + "-" +colIndex); - short dataFormat = cellStyle.getDataFormat(); - String formatString = cellStyle.getDataFormatString(); -// System.out.println(formatString); - boolean isMerge = !formatString.equals("General"); -// System.out.println(rowName); - if (styleId != null) { - extractStyle(xlsxInfoVos, Integer.parseInt(styleId), styleXml, true, rowName, String.valueOf(i + 1), isConditionalFormatting); - } - XmlCursor cellXml = rowCursor.getObject().newCursor(); - cellXml.dispose(); - } - colIndex ++; - } - rowCursor.dispose(); - rowIndex ++; - } - rowXml.dispose(); - } - cursor.dispose(); - } catch (Exception e) { - e.printStackTrace(); - } - - List chartTypeEntries = getChartTypes(); - - - // 开始获取图表等信息(包含数据透视表) - try (XmlCursor drawingXmlcursor = worksheetXml.newCursor()) { - drawingXmlcursor.selectPath(namespace + "./ns:drawing"); - while (drawingXmlcursor.toNextSelection()) { - try (XmlCursor drawingXml = drawingXmlcursor.getObject().newCursor()) { - // 上指定的drawingList下进行查找 - List xlsxDrawingSheetVos = drawingSheetVOS.get(i); - // 1、已经获取到了对应sheet下的图表信息等 - // 开始进行查询 - for (XlsxDrawingSheetVo xlsxDrawingSheetVo : xlsxDrawingSheetVos) { - // TODO 校验文件名称有问题 - if (xlsxDrawingSheetVo.getTypeName().contains("chart")) { - // 添加考点 - addXlsxInfo(String.valueOf(i+1), "图表是否存在", "isChart", String.valueOf(0), "chart", "图表", "isChart", "是否存在", "", xlsxInfoVos); - // 说明是图表 - try (XmlCursor chartXml = xlsxDrawingSheetVo.getXmlCursor().newCursor()) { -// System.out.println(chartXml.xmlText()); - String chartNameSpace = getNamespace(chartXml.xmlText()); - // 开始获取标题 - XlsxInfoVo xlsxInfoVo = new XlsxInfoVo(); - XmlCursor titleXml = chartXml.newCursor(); -// System.out.println(titleXml.xmlText()); - titleXml.selectPath(chartNameSpace + ".//c:chart/c:title/c:tx/c:rich"); - while (titleXml.toNextSelection()) { - addXlsxInfo(String.valueOf(i+1), "图表标题是否存在", "isTitle", String.valueOf(0), "chart", "图表", "title", "标题", "", xlsxInfoVos); - - XmlCursor titleAnchorXml = titleXml.newCursor(); - titleAnchorXml.selectPath(chartNameSpace + ".//a:bodyPr/@anchor"); - if (titleAnchorXml.toNextSelection()) { - addXlsxInfo(String.valueOf(i+1), "图表标题位置", "a:bodyPr/@anchor", titleAnchorXml.getTextValue(), "chart", "图表", "title", "标题", "", xlsxInfoVos); - } - XmlCursor titleNameXml = titleXml.newCursor(); - titleNameXml.selectPath(chartNameSpace + ".//a:p/a:r/a:t"); - if (titleNameXml.toNextSelection()) { - addXlsxInfo(String.valueOf(i+1), "图表标题文本", "a:p/a:r/a:t", titleNameXml.getTextValue(), "chart", "图表", "title", "标题", "", xlsxInfoVos); - } - } -// titleXml.dispose(); - XmlCursor charTypeXml = chartXml.newCursor(); - charTypeXml.selectPath(chartNameSpace + ".//c:chart/c:plotArea"); - while (charTypeXml.toNextSelection()) { - addXlsxInfo(String.valueOf(i+1), "绘图是否存在", "c:chart/c:plotArea", String.valueOf(0), "chart", "图表", "plotArea", "绘图", "", xlsxInfoVos); - // 获取图表类型 - for (ChartTypeEntry chartTypeEntry : chartTypeEntries) { - XmlCursor charTypeXmlInfo = charTypeXml.newCursor(); - // 判断是否存在参数 -// System.out.println(charTypeXmlInfo.xmlText()); -// System.out.println(".//c:plotArea/" + chartTypeEntry.getTag()); - charTypeXmlInfo.selectPath(chartNameSpace + "./" + chartTypeEntry.getTag()); - if (charTypeXmlInfo.toNextSelection()) { - if (chartTypeEntry.getTag().equals("c:barChart")) { - // 说明要在继续判断值 - charTypeXmlInfo.selectPath(chartNameSpace + ".//c:barDir/@val"); - if (charTypeXmlInfo.toNextSelection()) { - String value = charTypeXmlInfo.getTextValue(); - if (value.equals("col")) { - addXlsxInfo(String.valueOf(i+1), "图表类型", "c:barDir/@val", "簇型柱状图", "chart", "图表", "plotArea","绘图", "", xlsxInfoVos); - } - } else { - addXlsxInfo(String.valueOf(i+1), "图表类型", chartTypeEntry.getTag(), chartTypeEntry.getDisplayName(), "chart", "图表", "plotArea","绘图", "", xlsxInfoVos); - } - } else { - addXlsxInfo(String.valueOf(i+1), "图表类型", chartTypeEntry.getTag(), chartTypeEntry.getDisplayName(), "chart", "图表", "plotArea","绘图", "", xlsxInfoVos); - } - - } - } - - // 获取X,Y轴信息 - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - } - } - } - } catch (IOException e) { - e.printStackTrace(); - } catch (InvalidFormatException e) { - throw new RuntimeException(e); - } - List xlsxInfos = new ArrayList<>(); - for (XlsxInfoVo xlsxInfoVo : xlsxInfoVos) { - WpsPptxJudgementDto wpsPptxJudgementDto = new WpsPptxJudgementDto(); - wpsPptxJudgementDto.setContentIn(xlsxInfoVo.getSheetName() + "@" + xlsxInfoVo.getTypeName() + "@" + xlsxInfoVo.getCell() + "@" + xlsxInfoVo.getSecondTypeName() + "@" + xlsxInfoVo.getChineseName() + "@"+ xlsxInfoVo.getValue()); - wpsPptxJudgementDto.setContent(xlsxInfoVo.getSheetName() + "@" + xlsxInfoVo.getType() + "@" + xlsxInfoVo.getCell() + "@" + xlsxInfoVo.getSecondType() + "@" + xlsxInfoVo.getEnglishName() + "@"+ xlsxInfoVo.getValue()); - wpsPptxJudgementDto.setScoreRate("1"); - xlsxInfos.add(wpsPptxJudgementDto); - } - // TODO - if (index == "1") { - List randomItems = getRandomItems(xlsxInfos, 50); - return randomItems; - } else { - return xlsxInfos; - } - } - - // 扁平化多维列表 - public static List getRandomItems(List list, int count) { - List copy = new ArrayList<>(list); // 创建副本,避免修改原列表 - Collections.shuffle(copy); // 打乱顺序 - return copy.subList(0, Math.min(count, copy.size())); // 抽取前count个 - } - - // 支持所有类型的单元格 - private static String getCellValue(Cell cell) { - switch (cell.getCellType()) { - case STRING: - return cell.getStringCellValue(); - - case NUMERIC: - if (DateUtil.isCellDateFormatted(cell)) { - return cell.getDateCellValue().toString(); - } - return String.valueOf(cell.getNumericCellValue()); - - case BOOLEAN: - return String.valueOf(cell.getBooleanCellValue()); - - case FORMULA: - return cell.getCellFormula(); // 或者用 cell.getNumericCellValue() 等 - - case BLANK: - return ""; - - default: - return "[UNKNOWN TYPE]"; - } - } - - public static int columnLetterToNumber(String column) { - int result = 0; - for (int i = 0; i < column.length(); i++) { - result = result * 26 + (column.charAt(i) - 'A' + 1); - } - return result; - } - - - public static boolean isCellInRange(String cellRef, String rangeRef) { - int[] cellPos = parseCellRef(cellRef); // [col, row] - int[] startPos = parseCellRef(rangeRef.split(":")[0]); // A2 - int[] endPos = parseCellRef(rangeRef.split(":")[1]); // O18 - - return cellPos[0] >= startPos[0] && cellPos[0] <= endPos[0] && - cellPos[1] >= startPos[1] && cellPos[1] <= endPos[1]; - } - - public static int[] parseCellRef(String ref) { - String colLetters = ref.replaceAll("\\d", ""); // 取字母部分,如 A - String rowDigits = ref.replaceAll("\\D", ""); // 取数字部分,如 7 - - int colNum = columnNameToIndex(colLetters); - int rowNum = Integer.parseInt(rowDigits); - return new int[]{colNum, rowNum}; - } - - public static int columnNameToIndex(String column) { - int result = 0; - for (int i = 0; i < column.length(); i++) { - result = result * 26 + (column.charAt(i) - 'A' + 1); - } - return result; - } - - - public static List getChartTypes() { - // 创建一个图表 - List chartTypes = new ArrayList<>(); - chartTypes.add(new ChartTypeEntry("c:barChart", "横向柱状图")); - chartTypes.add(new ChartTypeEntry("c:lineChart", "折线图")); - chartTypes.add(new ChartTypeEntry("c:pieChart", "饼图")); - chartTypes.add(new ChartTypeEntry("c:areaChart", "面积图")); - chartTypes.add(new ChartTypeEntry("c:scatterChart", "散点图")); - chartTypes.add(new ChartTypeEntry("c:bubbleChart", "气泡图")); - chartTypes.add(new ChartTypeEntry("c:radarChart", "雷达图")); - chartTypes.add(new ChartTypeEntry("c:stockChart", "股票图")); - chartTypes.add(new ChartTypeEntry("c:surfaceChart", "曲面图")); - chartTypes.add(new ChartTypeEntry("c:ofPieChart", "分类饼图(饼中饼/条中饼)")); - chartTypes.add(new ChartTypeEntry("c:doughnutChart", "圆环图")); - chartTypes.add(new ChartTypeEntry("c:bar3DChart", "3D柱状图")); - chartTypes.add(new ChartTypeEntry("c:line3DChart", "3D折线图")); - chartTypes.add(new ChartTypeEntry("c:area3DChart", "3D面积图")); - chartTypes.add(new ChartTypeEntry("c:surface3DChart", "3D曲面图")); - return chartTypes; - } - - public static void addXlsxInfo(String sheetName, String chineseName, String englishName, String value, String type, String typeName, String secondType, String secondTypeName, String cellName, List xlsxInfoVos) { - XlsxInfoVo xlsxInfoVo = new XlsxInfoVo(); - xlsxInfoVo.setSheetNumber(sheetName); - // 拼接数据 - sheetName = "【sheet" + sheetName + "】"; - xlsxInfoVo.setSheetName(sheetName); - xlsxInfoVo.setChineseName(chineseName); - xlsxInfoVo.setEnglishName(englishName); - xlsxInfoVo.setValue(value); - xlsxInfoVo.setType(type); - xlsxInfoVo.setTypeName(typeName); - xlsxInfoVo.setCell(cellName); - xlsxInfoVo.setSecondType(secondType); - xlsxInfoVo.setSecondTypeName(secondTypeName); - xlsxInfoVos.add(xlsxInfoVo); - } - - public static String drawingXmlInfo(XmlCursor cursor, String sheetName) throws Exception { - // 判断是否存在表格数据 标签数据 - try (XmlCursor drawingXml = cursor.newCursor()) { - drawingXml.selectPath(namespace + "./ns:drawing"); - int drawingIndex = 0; - while (drawingXml.toNextSelection()) { - try (XmlCursor drawingXmlCursor = drawingXml.getObject().newCursor()) { -// System.out.println(drawingXmlCursor.xmlText()); - drawingXmlCursor.selectPath("declare namespace r='http://schemas.openxmlformats.org/officeDocument/2006/relationships' ./@r:id"); - if (drawingXmlCursor.toNextSelection()) { - String rId = drawingXmlCursor.getTextValue(); - - } - } - drawingIndex ++; - } - } - return ""; - } - - /** - * 从 Excel 文件中提取共享字符串 - * @param excelFilePath Excel 文件路径 - * @return 共享字符串数组 - * @throws Exception 如果文件不存在或无法读取,则抛出异常 - */ - public static String[] extractSharedStrings(String excelFilePath) throws Exception { - // 解压 Excel 文件并读取 sharedStrings.xml - ZipFile zipFile = new ZipFile(excelFilePath); - // 找到 sharedStrings.xml 文件的路径 - ZipEntry sharedStringsEntry = zipFile.getEntry("xl/sharedStrings.xml"); - - // 如果找不到 sharedStrings.xml,则返回空数组 - if (sharedStringsEntry == null) { - zipFile.close(); - return new String[0]; - } - - // 读取 sharedStrings.xml 文件 - InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); - byte[] content = inputStream.readAllBytes(); - String xmlContent = new String(content); - - // 使用 XmlObject 解析 sharedStrings.xml - XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); - XmlCursor cursor = xmlObject.newCursor(); - // 查询所有 sharedString 元素 - cursor.selectPath(namespace + "//ns:sst/ns:si"); - - List sharedStringList = new ArrayList<>(); - - // 遍历每个 sharedString 元素并提取文本值 - while (cursor.toNextSelection()) { - // 获取单元格内容 - String sharedString = cursor.getTextValue(); - sharedStringList.add(sharedString); - } - - cursor.dispose(); // 关闭游标 - zipFile.close(); // 关闭 zip 文件 - - // 将 List 转换为数组并返回 - return sharedStringList.toArray(new String[0]); - } - - public static XmlCursor extractStyle(List xlsxInfoVos, int serialNumber, XmlCursor cursor, boolean isTrue, String colName, String sheetName, boolean isCellStyle) throws Exception { - XmlCursor xmlCursor = cursor.newCursor(); - if (isTrue) { - // 自定义格式 - xmlCursor.selectPath(namespace + "//ns:cellXfs/ns:xf"); - } else { -// xlsxStyleCellStyleXfxVo.setCol(colName); - xmlCursor.selectPath(namespace + "//ns:cellStyleXfs/ns:xf"); - } - int index = 0; - String numFmtId = null; - String fontId = null; - String fillId = null; - String borderId = null; - String applyFont = null; - String applyFill = null; - String applyProtection = null; - String wrapText = null; - String textRotation = null; - String shrinkToFit = null; - String applyBorder = null; - String applyNumberFormat = null; - String applyAlignment = null; - while(xmlCursor.toNextSelection()) { - // 通过序号查询指定数据 - if (index == serialNumber) { - XmlCursor designateXml = xmlCursor.getObject().newCursor(); - // 数字格式的ID - numFmtId = designateXml.getAttributeText(new QName("numFmtId")); - // 字体的ID - fontId = designateXml.getAttributeText(new QName("fontId")); - // 填充(背景颜色)的ID - fillId = designateXml.getAttributeText(new QName("fillId")); - // 边框样式的ID - borderId = designateXml.getAttributeText(new QName("borderId")); - // 字体设置 - applyFont = designateXml.getAttributeText(new QName("applyFont")); - // 背景填充 - applyFill = designateXml.getAttributeText(new QName("applyFill")); - // 表示不应用保护设置(即不锁定单元格) - applyProtection = designateXml.getAttributeText(new QName("applyProtection")); - // 文本旋转45度 - wrapText = designateXml.getAttributeText(new QName("wrapText")); - // 文本缩进一级。 - textRotation = designateXml.getAttributeText(new QName("textRotation")); - // 启用文本自动缩小以适应单元格。 - shrinkToFit = designateXml.getAttributeText(new QName("shrinkToFit")); - applyBorder = designateXml.getAttributeText(new QName("applyBorder")); - applyNumberFormat = designateXml.getAttributeText(new QName("applyNumberFormat")); - applyAlignment = designateXml.getAttributeText(new QName("applyAlignment")); - designateXml.selectPath(namespace + "./ns:alignment"); - if (designateXml.toNextSelection()) { - // 获取 水平对齐 属性 - String horizontal = designateXml.getAttributeText(new QName("horizontal")); - // 获取 垂直对齐 属性 - String vertical = designateXml.getAttributeText(new QName("vertical")); - if (isTrue) { - addXlsxInfo(sheetName, "水平对齐", "vertical", horizontal, "cell", "单元格", "alignment", "对齐", colName, xlsxInfoVos); - addXlsxInfo(sheetName, "垂直对齐", "horizontal", vertical, "cell", "单元格", "alignment", "对齐", colName, xlsxInfoVos); - } else { -// xlsxStyleCellStyleXfxVo.setVertical(vertical); -// xlsxStyleCellStyleXfxVo.setHorizontal(horizontal); - } - } - break; - } - index ++; - } - // 接着进行查找 - if (numFmtId != null) { - try (XmlCursor cursorNumFmts = cursor.newCursor()) { - cursorNumFmts.selectPath(namespace + "//ns:numFmts/ns:numFmt"); - while (cursorNumFmts.toNextSelection()) { - // 获取 numFmtId 属性 - String numFmtIdInfo = cursorNumFmts.getAttributeText(new QName("numFmtId")); - if (numFmtIdInfo.equals(numFmtId)) { - // 获取 formatCode 属性 - String formatCode = cursorNumFmts.getAttributeText(new QName("formatCode")); - if (isTrue) { - addXlsxInfo(sheetName, "formatCode", "formatCode", formatCode, "cell", "单元格", "formatCode", "自定义格式", colName, xlsxInfoVos); - } else { -// xlsxStyleCellStyleXfxVo.setFormatCode(formatCode); - } - break; - } - } - } - } - xmlCursor.dispose(); - // 应用了字体设置 - if (fontId != null) { - try (XmlCursor cursorFonts = cursor.newCursor()) { - cursorFonts.selectPath(namespace + "//ns:fonts/ns:font"); - int fontIndex = 0; - while (cursorFonts.toNextSelection()) { - if (fontIndex == Integer.parseInt(fontId)) { - // 判断是否加粗(是否存在 标签) - try (XmlCursor cursorsFontBold = cursorFonts.getObject().newCursor()){ - cursorsFontBold.selectPath(namespace + "./ns:b"); - boolean isBold = cursorsFontBold.toNextSelection(); - addXlsxInfo(sheetName, "文本加粗", "ns:b", String.valueOf(isBold), "cell", "单元格", "font", "字体", colName, xlsxInfoVos); - cursorsFontBold.dispose(); - } - // 获取 sz 的 val 属性(字体大小) - try (XmlCursor cursorsFontSz = cursorFonts.getObject().newCursor()){ - cursorsFontSz.selectPath(namespace + "./ns:sz"); - if (cursorsFontSz.toNextSelection()) { - String fontSize = cursorsFontSz.getAttributeText(new QName("val")); - addXlsxInfo(sheetName, "文本大小", "ns:sz", fontSize, "cell", "单元格", "font", "字体", colName, xlsxInfoVos); - } - cursorsFontSz.dispose(); - } - // 获取 color 的 rgb 属性(字体颜色) - try (XmlCursor cursorsFontColor = cursorFonts.getObject().newCursor()){ - cursorsFontColor.selectPath(namespace + "./ns:color"); - if (cursorsFontColor.toNextSelection()) { - String fontColor = cursorsFontColor.getAttributeText(new QName("rgb")); - addXlsxInfo(sheetName, "文本颜色", "ns:color", fontColor, "cell", "单元格", "font", "字体", colName, xlsxInfoVos); - } - cursorsFontColor.dispose(); - } - // 获取 name 的 val 属性(字体名称) - try (XmlCursor cursorsFontName = cursorFonts.getObject().newCursor()){ - cursorsFontName.selectPath(namespace + "./ns:name"); - if (cursorsFontName.toNextSelection()) { - String fontName = cursorsFontName.getAttributeText(new QName("val")); - addXlsxInfo(sheetName, "字体名称", "ns:name", fontName, "cell", "单元格", "font", "字体", colName, xlsxInfoVos); - - } - cursorsFontName.dispose(); - } - // 获取 charset 的 val 属性(字符集) - try (XmlCursor cursorsFontCharset = cursorFonts.getObject().newCursor()){ - cursorsFontCharset.selectPath(namespace + "./ns:charset"); - if (cursorsFontCharset.toNextSelection()) { - String fontCharset = cursorsFontCharset.getAttributeText(new QName("val")); - addXlsxInfo(sheetName, "字体字符集", "ns:charset", fontCharset, "cell", "单元格", "font", "字体", colName, xlsxInfoVos); - - } - cursorsFontCharset.dispose(); - } - // 获取 scheme 的 val 属性(字体方案) - try (XmlCursor cursorsFontScheme = cursorFonts.getObject().newCursor()){ - cursorsFontScheme.selectPath(namespace + "./ns:scheme"); - if (cursorsFontScheme.toNextSelection()) { - String fontScheme = cursorsFontScheme.getAttributeText(new QName("val")); - addXlsxInfo(sheetName, "字体方案", "ns:scheme", fontScheme, "cell", "单元格", "font", "字体", colName, xlsxInfoVos); - - } - cursorsFontScheme.dispose(); - } - break; - } - fontIndex ++; - } - cursorFonts.dispose(); - } - } - // 背景颜色填充 - if (fillId != null) { - try (XmlCursor cursorFills = cursor.newCursor()) { - if (!isCellStyle) { - cursorFills.selectPath(namespace + "//ns:fills/ns:fill"); - int fillIndex = 0; - while (cursorFills.toNextSelection()) { - if (fillIndex == Integer.parseInt(fillId)) { - try (XmlCursor cursorsFill = cursorFills.getObject().newCursor()) { - cursorsFill.selectPath(namespace + "./ns:patternFill"); - if (cursorsFill.toNextSelection()) { - // 获取 patternType 属性(填充样式) - String patternType = cursorsFill.getAttributeText(new QName("patternType")); - addXlsxInfo(sheetName, "填充样式", "ns:scheme/@theme", patternType, "cell", "单元格", "fill", "背景", colName, xlsxInfoVos); - // 获取 fgColor 的 theme 和 tint 属性(填充颜色) - try (XmlCursor cursorsFgColor = cursorsFill.getObject().newCursor()) { - cursorsFgColor.selectPath(namespace + "./ns:fgColor"); - if (cursorsFgColor.toNextSelection()) { - String theme = cursorsFgColor.getAttributeText(new QName("theme")); - String rgb = cursorsFgColor.getAttributeText(new QName("rgb")); - addXlsxInfo(sheetName, "填充theme", "ns:scheme/@theme", theme, "cell", "单元格", "fill", "背景", colName, xlsxInfoVos); - addXlsxInfo(sheetName, "填充颜色", "ns:fgColor/@rgb", rgb, "cell", "单元格", "fill", "背景", colName, xlsxInfoVos); - } - cursorsFgColor.dispose(); - } - // 获取 bgColor 的 indexed 属性(背景色) - try (XmlCursor cursorsBgColor = cursorFills.getObject().newCursor()) { - cursorsBgColor.selectPath(namespace + "./ns:bgColor"); - if (cursorsBgColor.toNextSelection()) { - String rgb = cursorsBgColor.getAttributeText(new QName("rgb")); - addXlsxInfo(sheetName, "背景色", "ns:bgColor/@rgb", rgb, "cell", "单元格", "fill", "背景", colName, xlsxInfoVos); - } - cursorsBgColor.dispose(); - } - } - } - break; - } - fillIndex ++; - } - cursorFills.dispose(); - } else { - XmlCursor cursorDxf = cursorFills.newCursor(); - cursorDxf.selectPath(namespace + "//ns:dxfs/ns:dxf"); - int dxfIndex = 0; - while (cursorDxf.toNextSelection()) { - if (dxfIndex == dxfId) { - XmlCursor fontXmlCursor = cursorDxf.getObject().newCursor(); - fontXmlCursor.selectPath(namespace + "./ns:font/color/@rgb"); - if (fontXmlCursor.toNextSelection()) { - addXlsxInfo(sheetName, "文本颜色", "ns:color", fontXmlCursor.getTextValue(), "cell", "单元格", "font", "字体", colName, xlsxInfoVos); - } - fontXmlCursor.dispose(); - XmlCursor fillXmlCursor = cursorDxf.getObject().newCursor(); - fillXmlCursor.selectPath(namespace + "./ns:fill/ns:patternFill/ns:bgColor/@rgb"); - if (fillXmlCursor.toNextSelection()) { - addXlsxInfo(sheetName, "背景色", "ns:bgColor/@rgb", fillXmlCursor.getTextValue(), "cell", "单元格", "fill", "背景", colName, xlsxInfoVos); - } - fillXmlCursor.dispose(); - } - } - } - } - } - // 是否启用了边框设置 - if (borderId != null) { - try (XmlCursor cursorBorder = cursor.newCursor()) { - cursorBorder.selectPath(namespace + "//ns:borders/ns:border"); - int borderIndex = 0; - while (cursorBorder.toNextSelection()) { - if (borderIndex == Integer.parseInt(borderId)) { - // 定义对角线边框。常用于带有斜线的单元格。如果 标签存在,表示对角线有边框,否则没有。 - try (XmlCursor cursorsDiagonal = cursorBorder.getObject().newCursor()){ - cursorsDiagonal.selectPath(namespace + "./ns:diagonal"); - boolean isDiagonal = cursorsDiagonal.toNextSelection(); - addXlsxInfo(sheetName, "斜线的单元格", "ns:diagonal", String.valueOf(isDiagonal), "cell", "单元格", "border", "边框", colName, xlsxInfoVos); - cursorsDiagonal.dispose(); - } - // 获取上边框 - try (XmlCursor cursorsTop = cursorBorder.getObject().newCursor()){ - XmlCursor cursorsTops = cursorBorder.getObject().newCursor(); - cursorsTops.selectPath(namespace + "./ns:top"); - if (cursorsTops.toNextSelection()) { - // 样式 - String topStyle = cursorsTops.getAttributeText(new QName("style")); - addXlsxInfo(sheetName, "上边框", "ns:top/@style", topStyle, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); - - } - cursorsTops.selectPath(namespace + "./ns:color"); - if (cursorsTops.toNextSelection()) { - String topColor = cursorsTops.getAttributeText(new QName("rgb")); - addXlsxInfo(sheetName, "上边框颜色", "ns:top/@rgb", topColor, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); - - } - cursorsTops.dispose(); - cursorsTop.dispose(); - } - // 获取下边框 - try (XmlCursor cursorsBottom = cursorBorder.getObject().newCursor()){ - XmlCursor cursorsBottoms = cursorBorder.getObject().newCursor(); - cursorsBottoms.selectPath(namespace + "./ns:bottom"); - if (cursorsBottoms.toNextSelection()) { - // 样式 - String bottomStyle = cursorsBottoms.getAttributeText(new QName("style")); - addXlsxInfo(sheetName, "下边框", "ns:top/@rgb", bottomStyle, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); - - } - // 颜色 - cursorsBottoms.selectPath(namespace + "./ns:color"); - if (cursorsBottoms.toNextSelection()) { - String bottomColor = cursorsBottoms.getAttributeText(new QName("rgb")); - addXlsxInfo(sheetName, "下边框颜色", "ns:top/@rgb", bottomColor, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); - - } - cursorsBottoms.dispose(); - cursorsBottom.dispose(); - } - // 获取左边框 - try (XmlCursor cursorsLeft = cursorBorder.getObject().newCursor()){ - XmlCursor cursorsLefts = cursorBorder.getObject().newCursor(); - cursorsLefts.selectPath(namespace + "./ns:left"); - if (cursorsLefts.toNextSelection()) { - // 样式 - String leftStyle = cursorsLefts.getAttributeText(new QName("style")); - addXlsxInfo(sheetName, "左边框", "ns:top/@rgb", leftStyle, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); - } - // 颜色 - cursorsLefts.selectPath(namespace + "./ns:color"); - if (cursorsLefts.toNextSelection()) { - String leftColor = cursorsLefts.getAttributeText(new QName("rgb")); - addXlsxInfo(sheetName, "左边框颜色", "ns:top/@rgb", leftColor, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); - - } - cursorsLefts.dispose(); - cursorsLeft.dispose(); - } - // 获取右边框 - try (XmlCursor cursorsRight = cursorBorder.getObject().newCursor()){ - XmlCursor cursorsRights = cursorBorder.getObject().newCursor(); - cursorsRights.selectPath(namespace + "./ns:right"); - if (cursorsRights.toNextSelection()) { - // 样式 - String rightStyle = cursorsRights.getAttributeText(new QName("style")); - addXlsxInfo(sheetName, "右边框", "ns:top/@rgb", rightStyle, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); - - } - // 颜色 - cursorsRights.selectPath(namespace + "./ns:color"); - if (cursorsRights.toNextSelection()) { - String rightColor = cursorsRights.getAttributeText(new QName("rgb")); - addXlsxInfo(sheetName, "右边框颜色", "ns:top/@rgb", rightColor, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); - } - cursorsRights.dispose(); - cursorsRight.dispose(); - } - break; - } - borderIndex ++; - } - cursorBorder.dispose(); - } - } - return cursor; - } - - public static XmlCursor extractStyleXml(String excelFilePath) throws Exception { - // 解压 Excel 文件并读取 sharedStrings.xml - ZipFile zipFile = new ZipFile(excelFilePath); - // 找到 sharedStrings.xml 文件的路径 - ZipEntry sharedStringsEntry = zipFile.getEntry("xl/styles.xml"); - - // 如果找不到 sharedStrings.xml,则返回空数组 - if (sharedStringsEntry == null) { - zipFile.close(); - return null; - } - - // 读取 sharedStrings.xml 文件 - InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); - byte[] content = inputStream.readAllBytes(); - String xmlContent = new String(content); - // 使用 XmlObject 解析 sharedStrings.xml - XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); - XmlCursor cursor = xmlObject.newCursor(); - zipFile.close(); // 关闭 zip 文件 - return cursor; - } - - public static XmlCursor extractConnectionsXml(String excelFilePath) throws Exception { - // 解压 Excel 文件并读取 sharedStrings.xml - ZipFile zipFile = new ZipFile(excelFilePath); - // 找到 sharedStrings.xml 文件的路径 - ZipEntry sharedStringsEntry = zipFile.getEntry("xl/connections.xml"); - - // 如果找不到 sharedStrings.xml,则返回空数组 - if (sharedStringsEntry == null) { - zipFile.close(); - return null; - } - - // 读取 sharedStrings.xml 文件 - InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); - byte[] content = inputStream.readAllBytes(); - String xmlContent = new String(content); - // 使用 XmlObject 解析 sharedStrings.xml - XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); - XmlCursor cursor = xmlObject.newCursor(); - zipFile.close(); // 关闭 zip 文件 - return cursor; - } - -// public static String getDrawingInfo(String excelFilePath) throws Exception { +// setWordInfo("列", "cols", "cols", filePath, thirdIdCol, secondIdSheet, excelInfoReqVoList); +//// String thirdIdCol = getStringRandom(); +// // 判断是否存在图表 +// setWordInfo("列", "cols", "cols", filePath, thirdIdCol, secondIdSheet, excelInfoReqVoList); +// +// System.out.println(worksheetXml.xmlText()); +// } +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (InvalidFormatException e) { +// throw new RuntimeException(e); +// } +// +// +// return excelInfoReqVoList; +// } +// public static void setWordInfo(String chineseName, String englishName, String selectName, String filePath, String id, String parentId, List excelInfoReqVos) throws Exception { +// ExcelInfoReqVo excelInfos = new ExcelInfoReqVo(); +// excelInfos.setName(chineseName); +// excelInfos.setEnglishName(englishName); +// excelInfos.setFilePath(filePath); +// excelInfos.setId(id); +// excelInfos.setSelectName(selectName); +// excelInfos.setParentId(parentId); +// excelInfoReqVos.add(excelInfos); +// } +// +// +// public static List wpsExcel(String filePath, String index) throws Exception { +// // 获取共享字符串 +// String[] sharedStrings = extractSharedStrings(filePath); +// // 读取样式xml +// XmlCursor styleXml = extractStyleXml(filePath); +// // 作簿中的数据连接(Data Connections),即 Excel 与外部数据源(如数据库、Web 服务、其他文件等)的链接信息 +// XmlCursor connectionsXml = extractConnectionsXml(filePath); +// // 获取工作簿中的图表数据 +//// List chartListXmls = extractChartXml(filePath); +// getDrawingInfos(filePath); +// // 单元格数据 +// List xlsxInfoVos = new ArrayList<>(); +// try (FileInputStream fis = new FileInputStream(filePath); +// OPCPackage pkg = OPCPackage.open(fis); +// XSSFWorkbook workbook = new XSSFWorkbook(pkg)) { +// // 获取有多少个工作表 +// int sheetNumber = workbook.getNumberOfSheets(); +// for (int i = 0; i < sheetNumber; i++) { +//// System.out.println("第 " + (i + 1) + " 个工作表"); +// // 获取工作表内容 +// XSSFSheet sheetXss = workbook.getSheetAt(i); +// // 获取工作表的XML对象 +// XmlObject worksheetXml = sheetXss.getCTWorksheet(); +// // 读取条件格式,并转化条件 +// XmlCursor conditionalFormatting = worksheetXml.newCursor(); +// conditionalFormatting.selectPath(namespace + "//ns:conditionalFormatting"); +// String sqref = ""; +// String formula = ""; +// boolean conditionalFormattingFlag = false; +// if (conditionalFormatting.toNextSelection()) { +// conditionalFormattingFlag = true; +// // 使用了条件格式,作用范围 +// XmlCursor sqrefXml = conditionalFormatting.getObject().newCursor(); +// sqrefXml.selectPath(namespace + "./@sqref"); +// if (sqrefXml.toNextSelection()) { +// sqref = sqrefXml.getTextValue(); +// } +// // 查询条件 +// XmlCursor cfRuleXml = conditionalFormatting.getObject().newCursor(); +// cfRuleXml.selectPath(namespace + "./ns:cfRule"); +// if (cfRuleXml.toNextSelection()){ +// dxfId = Integer.parseInt(cfRuleXml.getAttributeText(new QName("dxfId"))); +// XmlCursor formulaXml = cfRuleXml.getObject().newCursor(); +// formulaXml.selectPath(namespace + "./ns:formula"); +// if (formulaXml.toNextSelection()) { +// formula = cfRuleXml.getTextValue(); +// } +// } +// } +// try (XmlCursor cursor = worksheetXml.newCursor()) { +//// drawingXmlInfo(cursor, String.valueOf(i+1)); +// // 查询所有 row 元素 +// cursor.selectPath(namespace + "//ns:worksheet/ns:sheetData/ns:row"); +// int rowIndex = 0; +// while (cursor.toNextSelection()) { +// // 行的参数 +// XmlCursor rowXml = cursor.getObject().newCursor(); +// addXlsxInfo(String.valueOf(i+1), "行高", "ns:row/@ht", rowXml.getAttributeText(new QName("ht")), "row", "行" + rowXml.getAttributeText(new QName("r")), "style", "样式", "r"+rowXml.getAttributeText(new QName("r")), xlsxInfoVos); +// addXlsxInfo(String.valueOf(i+1), "行高", "ns:row/@ht", rowXml.getAttributeText(new QName("ht")), "row", "行" + rowXml.getAttributeText(new QName("r")),"style", "样式", "r"+rowXml.getAttributeText(new QName("r")), xlsxInfoVos); +// +// +// try (XmlCursor rowCursor = rowXml.newCursor()) { +// rowCursor.selectPath(namespace + "./ns:c"); +// // 接着获取单元格 +// int colIndex = 0; +// while (rowCursor.toNextSelection()) { +// // 判断是否使用了条件样式进行判断值 +// boolean isConditionalFormatting = false; +// if (conditionalFormattingFlag) { +// // 进行拆分单元格 +// // 1. 提取列字母(正则匹配 $K2 或 K2) +// // 字符串替换 +// String formulas = formula.replaceAll("\\$", "").split("=")[0]; +// Pattern pattern = Pattern.compile("^[A-Za-z]+"); +// Matcher matcher = pattern.matcher(formulas); +// String colLetters = ""; +// while (matcher.find()) { +// colLetters = matcher.group(0); +// } +// int colIndexMatcher = columnLetterToNumber(colLetters); +// // 读取指定单元格 +// Row row = sheetXss.getRow(rowIndex); +// if (row == null) { +// break; +// } +// Cell cell = row.getCell(colIndexMatcher-1); +// String value = getCellValue(cell); +// // 获取对比值 +// String compareValue = formula.split("=")[1].replace("\"", "");; +// if (Objects.equals(value, compareValue)) { +// isConditionalFormatting = true; +// } +// } +// Row row = sheetXss.getRow(rowIndex); +// if (row == null) { +// break; +// } +// // 获取行属性 +// Cell cell = row.getCell(colIndex); +// if (row != null && cell != null) { +// // 获取单元格 +// String rowName = rowCursor.getAttributeText(new QName("r")); +// // 获取style编号 +// String styleId = rowCursor.getAttributeText(new QName("s")); +// // 获取共享字符串 +// String tName = rowCursor.getAttributeText(new QName("t")); +// // 获取具体的值 +// try (XmlCursor valueXml = rowCursor.getObject().newCursor()) { +// String value = ""; +// valueXml.selectPath(namespace + "./ns:v"); +// if (valueXml.toNextSelection()) { +// value = valueXml.getTextValue(); +// } +// // 如果是共享字符串 +// if (tName != null && tName.equals("s")) { +// value = sharedStrings[Integer.parseInt(value)]; +// addXlsxInfo(String.valueOf(i+1), "单元格文本", "ns:celltext", value, "cell", "单元格", "text", "文本", rowName, xlsxInfoVos); +// } else { +// addXlsxInfo(String.valueOf(i+1), "单元格文本", "ns:celltext", value, "cell", "单元格", "text", "文本", rowName, xlsxInfoVos); +// } +// +// valueXml.dispose(); +// } +// // 获取公式 +// try (XmlCursor formulaXml = rowCursor.getObject().newCursor()) { +// String value = ""; +// formulaXml.selectPath(namespace + "./ns:f"); +// if (formulaXml.toNextSelection()) { +// value = formulaXml.getTextValue(); +// addXlsxInfo(String.valueOf(i+1), "单元格公式", "ns:formula", value, "cell", "单元格", "text", "文本", rowName, xlsxInfoVos); +// } +// formulaXml.dispose(); +// } +// // 获取单元格的格式 +// CellStyle cellStyle = cell.getCellStyle(); +//// System.out.println(rowIndex + "-" +colIndex); +// short dataFormat = cellStyle.getDataFormat(); +// String formatString = cellStyle.getDataFormatString(); +//// System.out.println(formatString); +// boolean isMerge = !formatString.equals("General"); +//// System.out.println(rowName); +// if (styleId != null) { +// extractStyle(xlsxInfoVos, Integer.parseInt(styleId), styleXml, true, rowName, String.valueOf(i + 1), isConditionalFormatting); +// } +// XmlCursor cellXml = rowCursor.getObject().newCursor(); +// cellXml.dispose(); +// } +// colIndex ++; +// } +// rowCursor.dispose(); +// rowIndex ++; +// } +// rowXml.dispose(); +// } +// cursor.dispose(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// List chartTypeEntries = getChartTypes(); +// +// +// // 开始获取图表等信息(包含数据透视表) +// try (XmlCursor drawingXmlcursor = worksheetXml.newCursor()) { +// drawingXmlcursor.selectPath(namespace + "./ns:drawing"); +// while (drawingXmlcursor.toNextSelection()) { +// try (XmlCursor drawingXml = drawingXmlcursor.getObject().newCursor()) { +// // 上指定的drawingList下进行查找 +// List xlsxDrawingSheetVos = drawingSheetVOS.get(i); +// // 1、已经获取到了对应sheet下的图表信息等 +// // 开始进行查询 +// for (XlsxDrawingSheetVo xlsxDrawingSheetVo : xlsxDrawingSheetVos) { +// // TODO 校验文件名称有问题 +// if (xlsxDrawingSheetVo.getTypeName().contains("chart")) { +// // 添加考点 +// addXlsxInfo(String.valueOf(i+1), "图表是否存在", "isChart", String.valueOf(0), "chart", "图表", "isChart", "是否存在", "", xlsxInfoVos); +// // 说明是图表 +// try (XmlCursor chartXml = xlsxDrawingSheetVo.getXmlCursor().newCursor()) { +//// System.out.println(chartXml.xmlText()); +// String chartNameSpace = getNamespace(chartXml.xmlText()); +// // 开始获取标题 +// XlsxInfoVo xlsxInfoVo = new XlsxInfoVo(); +// XmlCursor titleXml = chartXml.newCursor(); +//// System.out.println(titleXml.xmlText()); +// titleXml.selectPath(chartNameSpace + ".//c:chart/c:title/c:tx/c:rich"); +// while (titleXml.toNextSelection()) { +// addXlsxInfo(String.valueOf(i+1), "图表标题是否存在", "isTitle", String.valueOf(0), "chart", "图表", "title", "标题", "", xlsxInfoVos); +// +// XmlCursor titleAnchorXml = titleXml.newCursor(); +// titleAnchorXml.selectPath(chartNameSpace + ".//a:bodyPr/@anchor"); +// if (titleAnchorXml.toNextSelection()) { +// addXlsxInfo(String.valueOf(i+1), "图表标题位置", "a:bodyPr/@anchor", titleAnchorXml.getTextValue(), "chart", "图表", "title", "标题", "", xlsxInfoVos); +// } +// XmlCursor titleNameXml = titleXml.newCursor(); +// titleNameXml.selectPath(chartNameSpace + ".//a:p/a:r/a:t"); +// if (titleNameXml.toNextSelection()) { +// addXlsxInfo(String.valueOf(i+1), "图表标题文本", "a:p/a:r/a:t", titleNameXml.getTextValue(), "chart", "图表", "title", "标题", "", xlsxInfoVos); +// } +// } +//// titleXml.dispose(); +// XmlCursor charTypeXml = chartXml.newCursor(); +// charTypeXml.selectPath(chartNameSpace + ".//c:chart/c:plotArea"); +// while (charTypeXml.toNextSelection()) { +// addXlsxInfo(String.valueOf(i+1), "绘图是否存在", "c:chart/c:plotArea", String.valueOf(0), "chart", "图表", "plotArea", "绘图", "", xlsxInfoVos); +// // 获取图表类型 +// for (ChartTypeEntry chartTypeEntry : chartTypeEntries) { +// XmlCursor charTypeXmlInfo = charTypeXml.newCursor(); +// // 判断是否存在参数 +//// System.out.println(charTypeXmlInfo.xmlText()); +//// System.out.println(".//c:plotArea/" + chartTypeEntry.getTag()); +// charTypeXmlInfo.selectPath(chartNameSpace + "./" + chartTypeEntry.getTag()); +// if (charTypeXmlInfo.toNextSelection()) { +// if (chartTypeEntry.getTag().equals("c:barChart")) { +// // 说明要在继续判断值 +// charTypeXmlInfo.selectPath(chartNameSpace + ".//c:barDir/@val"); +// if (charTypeXmlInfo.toNextSelection()) { +// String value = charTypeXmlInfo.getTextValue(); +// if (value.equals("col")) { +// addXlsxInfo(String.valueOf(i+1), "图表类型", "c:barDir/@val", "簇型柱状图", "chart", "图表", "plotArea","绘图", "", xlsxInfoVos); +// } +// } else { +// addXlsxInfo(String.valueOf(i+1), "图表类型", chartTypeEntry.getTag(), chartTypeEntry.getDisplayName(), "chart", "图表", "plotArea","绘图", "", xlsxInfoVos); +// } +// } else { +// addXlsxInfo(String.valueOf(i+1), "图表类型", chartTypeEntry.getTag(), chartTypeEntry.getDisplayName(), "chart", "图表", "plotArea","绘图", "", xlsxInfoVos); +// } +// +// } +// } +// +// // 获取X,Y轴信息 +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } +// } +// } +// } +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (InvalidFormatException e) { +// throw new RuntimeException(e); +// } +// List xlsxInfos = new ArrayList<>(); +// for (XlsxInfoVo xlsxInfoVo : xlsxInfoVos) { +// WpsPptxJudgementDto wpsPptxJudgementDto = new WpsPptxJudgementDto(); +// wpsPptxJudgementDto.setContentIn(xlsxInfoVo.getSheetName() + "@" + xlsxInfoVo.getTypeName() + "@" + xlsxInfoVo.getCell() + "@" + xlsxInfoVo.getSecondTypeName() + "@" + xlsxInfoVo.getChineseName() + "@"+ xlsxInfoVo.getValue()); +// wpsPptxJudgementDto.setContent(xlsxInfoVo.getSheetName() + "@" + xlsxInfoVo.getType() + "@" + xlsxInfoVo.getCell() + "@" + xlsxInfoVo.getSecondType() + "@" + xlsxInfoVo.getEnglishName() + "@"+ xlsxInfoVo.getValue()); +// wpsPptxJudgementDto.setScoreRate("1"); +// xlsxInfos.add(wpsPptxJudgementDto); +// } +// // TODO +// if (index == "1") { +// List randomItems = getRandomItems(xlsxInfos, 50); +// return randomItems; +// } else { +// return xlsxInfos; +// } +// } +// +// // 扁平化多维列表 +// public static List getRandomItems(List list, int count) { +// List copy = new ArrayList<>(list); // 创建副本,避免修改原列表 +// Collections.shuffle(copy); // 打乱顺序 +// return copy.subList(0, Math.min(count, copy.size())); // 抽取前count个 +// } +// +// // 支持所有类型的单元格 +// private static String getCellValue(Cell cell) { +// switch (cell.getCellType()) { +// case STRING: +// return cell.getStringCellValue(); +// +// case NUMERIC: +// if (DateUtil.isCellDateFormatted(cell)) { +// return cell.getDateCellValue().toString(); +// } +// return String.valueOf(cell.getNumericCellValue()); +// +// case BOOLEAN: +// return String.valueOf(cell.getBooleanCellValue()); +// +// case FORMULA: +// return cell.getCellFormula(); // 或者用 cell.getNumericCellValue() 等 +// +// case BLANK: +// return ""; +// +// default: +// return "[UNKNOWN TYPE]"; +// } +// } +// +// public static int columnLetterToNumber(String column) { +// int result = 0; +// for (int i = 0; i < column.length(); i++) { +// result = result * 26 + (column.charAt(i) - 'A' + 1); +// } +// return result; +// } +// +// +// public static boolean isCellInRange(String cellRef, String rangeRef) { +// int[] cellPos = parseCellRef(cellRef); // [col, row] +// int[] startPos = parseCellRef(rangeRef.split(":")[0]); // A2 +// int[] endPos = parseCellRef(rangeRef.split(":")[1]); // O18 +// +// return cellPos[0] >= startPos[0] && cellPos[0] <= endPos[0] && +// cellPos[1] >= startPos[1] && cellPos[1] <= endPos[1]; +// } +// +// public static int[] parseCellRef(String ref) { +// String colLetters = ref.replaceAll("\\d", ""); // 取字母部分,如 A +// String rowDigits = ref.replaceAll("\\D", ""); // 取数字部分,如 7 +// +// int colNum = columnNameToIndex(colLetters); +// int rowNum = Integer.parseInt(rowDigits); +// return new int[]{colNum, rowNum}; +// } +// +// public static int columnNameToIndex(String column) { +// int result = 0; +// for (int i = 0; i < column.length(); i++) { +// result = result * 26 + (column.charAt(i) - 'A' + 1); +// } +// return result; +// } +// +// +// public static List getChartTypes() { +// // 创建一个图表 +// List chartTypes = new ArrayList<>(); +// chartTypes.add(new ChartTypeEntry("c:barChart", "横向柱状图")); +// chartTypes.add(new ChartTypeEntry("c:lineChart", "折线图")); +// chartTypes.add(new ChartTypeEntry("c:pieChart", "饼图")); +// chartTypes.add(new ChartTypeEntry("c:areaChart", "面积图")); +// chartTypes.add(new ChartTypeEntry("c:scatterChart", "散点图")); +// chartTypes.add(new ChartTypeEntry("c:bubbleChart", "气泡图")); +// chartTypes.add(new ChartTypeEntry("c:radarChart", "雷达图")); +// chartTypes.add(new ChartTypeEntry("c:stockChart", "股票图")); +// chartTypes.add(new ChartTypeEntry("c:surfaceChart", "曲面图")); +// chartTypes.add(new ChartTypeEntry("c:ofPieChart", "分类饼图(饼中饼/条中饼)")); +// chartTypes.add(new ChartTypeEntry("c:doughnutChart", "圆环图")); +// chartTypes.add(new ChartTypeEntry("c:bar3DChart", "3D柱状图")); +// chartTypes.add(new ChartTypeEntry("c:line3DChart", "3D折线图")); +// chartTypes.add(new ChartTypeEntry("c:area3DChart", "3D面积图")); +// chartTypes.add(new ChartTypeEntry("c:surface3DChart", "3D曲面图")); +// return chartTypes; +// } +// +// public static void addXlsxInfo(String sheetName, String chineseName, String englishName, String value, String type, String typeName, String secondType, String secondTypeName, String cellName, List xlsxInfoVos) { +// XlsxInfoVo xlsxInfoVo = new XlsxInfoVo(); +// xlsxInfoVo.setSheetNumber(sheetName); +// // 拼接数据 +// sheetName = "【sheet" + sheetName + "】"; +// xlsxInfoVo.setSheetName(sheetName); +// xlsxInfoVo.setChineseName(chineseName); +// xlsxInfoVo.setEnglishName(englishName); +// xlsxInfoVo.setValue(value); +// xlsxInfoVo.setType(type); +// xlsxInfoVo.setTypeName(typeName); +// xlsxInfoVo.setCell(cellName); +// xlsxInfoVo.setSecondType(secondType); +// xlsxInfoVo.setSecondTypeName(secondTypeName); +// xlsxInfoVos.add(xlsxInfoVo); +// } +// +// public static String drawingXmlInfo(XmlCursor cursor, String sheetName) throws Exception { +// // 判断是否存在表格数据 标签数据 +// try (XmlCursor drawingXml = cursor.newCursor()) { +// drawingXml.selectPath(namespace + "./ns:drawing"); +// int drawingIndex = 0; +// while (drawingXml.toNextSelection()) { +// try (XmlCursor drawingXmlCursor = drawingXml.getObject().newCursor()) { +//// System.out.println(drawingXmlCursor.xmlText()); +// drawingXmlCursor.selectPath("declare namespace r='http://schemas.openxmlformats.org/officeDocument/2006/relationships' ./@r:id"); +// if (drawingXmlCursor.toNextSelection()) { +// String rId = drawingXmlCursor.getTextValue(); +// +// } +// } +// drawingIndex ++; +// } +// } +// return ""; +// } +// +// /** +// * 从 Excel 文件中提取共享字符串 +// * @param excelFilePath Excel 文件路径 +// * @return 共享字符串数组 +// * @throws Exception 如果文件不存在或无法读取,则抛出异常 +// */ +// public static String[] extractSharedStrings(String excelFilePath) throws Exception { // // 解压 Excel 文件并读取 sharedStrings.xml // ZipFile zipFile = new ZipFile(excelFilePath); +// // 找到 sharedStrings.xml 文件的路径 +// ZipEntry sharedStringsEntry = zipFile.getEntry("xl/sharedStrings.xml"); +// +// // 如果找不到 sharedStrings.xml,则返回空数组 +// if (sharedStringsEntry == null) { +// zipFile.close(); +// return new String[0]; +// } +// +// // 读取 sharedStrings.xml 文件 +// InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); +// byte[] content = inputStream.readAllBytes(); +// String xmlContent = new String(content); +// +// // 使用 XmlObject 解析 sharedStrings.xml +// XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); +// XmlCursor cursor = xmlObject.newCursor(); +// // 查询所有 sharedString 元素 +// cursor.selectPath(namespace + "//ns:sst/ns:si"); +// +// List sharedStringList = new ArrayList<>(); +// +// // 遍历每个 sharedString 元素并提取文本值 +// while (cursor.toNextSelection()) { +// // 获取单元格内容 +// String sharedString = cursor.getTextValue(); +// sharedStringList.add(sharedString); +// } +// +// cursor.dispose(); // 关闭游标 +// zipFile.close(); // 关闭 zip 文件 +// +// // 将 List 转换为数组并返回 +// return sharedStringList.toArray(new String[0]); +// } +// +// public static XmlCursor extractStyle(List xlsxInfoVos, int serialNumber, XmlCursor cursor, boolean isTrue, String colName, String sheetName, boolean isCellStyle) throws Exception { +// XmlCursor xmlCursor = cursor.newCursor(); +// if (isTrue) { +// // 自定义格式 +// xmlCursor.selectPath(namespace + "//ns:cellXfs/ns:xf"); +// } else { +//// xlsxStyleCellStyleXfxVo.setCol(colName); +// xmlCursor.selectPath(namespace + "//ns:cellStyleXfs/ns:xf"); +// } +// int index = 0; +// String numFmtId = null; +// String fontId = null; +// String fillId = null; +// String borderId = null; +// String applyFont = null; +// String applyFill = null; +// String applyProtection = null; +// String wrapText = null; +// String textRotation = null; +// String shrinkToFit = null; +// String applyBorder = null; +// String applyNumberFormat = null; +// String applyAlignment = null; +// while(xmlCursor.toNextSelection()) { +// // 通过序号查询指定数据 +// if (index == serialNumber) { +// XmlCursor designateXml = xmlCursor.getObject().newCursor(); +// // 数字格式的ID +// numFmtId = designateXml.getAttributeText(new QName("numFmtId")); +// // 字体的ID +// fontId = designateXml.getAttributeText(new QName("fontId")); +// // 填充(背景颜色)的ID +// fillId = designateXml.getAttributeText(new QName("fillId")); +// // 边框样式的ID +// borderId = designateXml.getAttributeText(new QName("borderId")); +// // 字体设置 +// applyFont = designateXml.getAttributeText(new QName("applyFont")); +// // 背景填充 +// applyFill = designateXml.getAttributeText(new QName("applyFill")); +// // 表示不应用保护设置(即不锁定单元格) +// applyProtection = designateXml.getAttributeText(new QName("applyProtection")); +// // 文本旋转45度 +// wrapText = designateXml.getAttributeText(new QName("wrapText")); +// // 文本缩进一级。 +// textRotation = designateXml.getAttributeText(new QName("textRotation")); +// // 启用文本自动缩小以适应单元格。 +// shrinkToFit = designateXml.getAttributeText(new QName("shrinkToFit")); +// applyBorder = designateXml.getAttributeText(new QName("applyBorder")); +// applyNumberFormat = designateXml.getAttributeText(new QName("applyNumberFormat")); +// applyAlignment = designateXml.getAttributeText(new QName("applyAlignment")); +// designateXml.selectPath(namespace + "./ns:alignment"); +// if (designateXml.toNextSelection()) { +// // 获取 水平对齐 属性 +// String horizontal = designateXml.getAttributeText(new QName("horizontal")); +// // 获取 垂直对齐 属性 +// String vertical = designateXml.getAttributeText(new QName("vertical")); +// if (isTrue) { +// addXlsxInfo(sheetName, "水平对齐", "vertical", horizontal, "cell", "单元格", "alignment", "对齐", colName, xlsxInfoVos); +// addXlsxInfo(sheetName, "垂直对齐", "horizontal", vertical, "cell", "单元格", "alignment", "对齐", colName, xlsxInfoVos); +// } else { +//// xlsxStyleCellStyleXfxVo.setVertical(vertical); +//// xlsxStyleCellStyleXfxVo.setHorizontal(horizontal); +// } +// } +// break; +// } +// index ++; +// } +// // 接着进行查找 +// if (numFmtId != null) { +// try (XmlCursor cursorNumFmts = cursor.newCursor()) { +// cursorNumFmts.selectPath(namespace + "//ns:numFmts/ns:numFmt"); +// while (cursorNumFmts.toNextSelection()) { +// // 获取 numFmtId 属性 +// String numFmtIdInfo = cursorNumFmts.getAttributeText(new QName("numFmtId")); +// if (numFmtIdInfo.equals(numFmtId)) { +// // 获取 formatCode 属性 +// String formatCode = cursorNumFmts.getAttributeText(new QName("formatCode")); +// if (isTrue) { +// addXlsxInfo(sheetName, "formatCode", "formatCode", formatCode, "cell", "单元格", "formatCode", "自定义格式", colName, xlsxInfoVos); +// } else { +//// xlsxStyleCellStyleXfxVo.setFormatCode(formatCode); +// } +// break; +// } +// } +// } +// } +// xmlCursor.dispose(); +// // 应用了字体设置 +// if (fontId != null) { +// try (XmlCursor cursorFonts = cursor.newCursor()) { +// cursorFonts.selectPath(namespace + "//ns:fonts/ns:font"); +// int fontIndex = 0; +// while (cursorFonts.toNextSelection()) { +// if (fontIndex == Integer.parseInt(fontId)) { +// // 判断是否加粗(是否存在 标签) +// try (XmlCursor cursorsFontBold = cursorFonts.getObject().newCursor()){ +// cursorsFontBold.selectPath(namespace + "./ns:b"); +// boolean isBold = cursorsFontBold.toNextSelection(); +// addXlsxInfo(sheetName, "文本加粗", "ns:b", String.valueOf(isBold), "cell", "单元格", "font", "字体", colName, xlsxInfoVos); +// cursorsFontBold.dispose(); +// } +// // 获取 sz 的 val 属性(字体大小) +// try (XmlCursor cursorsFontSz = cursorFonts.getObject().newCursor()){ +// cursorsFontSz.selectPath(namespace + "./ns:sz"); +// if (cursorsFontSz.toNextSelection()) { +// String fontSize = cursorsFontSz.getAttributeText(new QName("val")); +// addXlsxInfo(sheetName, "文本大小", "ns:sz", fontSize, "cell", "单元格", "font", "字体", colName, xlsxInfoVos); +// } +// cursorsFontSz.dispose(); +// } +// // 获取 color 的 rgb 属性(字体颜色) +// try (XmlCursor cursorsFontColor = cursorFonts.getObject().newCursor()){ +// cursorsFontColor.selectPath(namespace + "./ns:color"); +// if (cursorsFontColor.toNextSelection()) { +// String fontColor = cursorsFontColor.getAttributeText(new QName("rgb")); +// addXlsxInfo(sheetName, "文本颜色", "ns:color", fontColor, "cell", "单元格", "font", "字体", colName, xlsxInfoVos); +// } +// cursorsFontColor.dispose(); +// } +// // 获取 name 的 val 属性(字体名称) +// try (XmlCursor cursorsFontName = cursorFonts.getObject().newCursor()){ +// cursorsFontName.selectPath(namespace + "./ns:name"); +// if (cursorsFontName.toNextSelection()) { +// String fontName = cursorsFontName.getAttributeText(new QName("val")); +// addXlsxInfo(sheetName, "字体名称", "ns:name", fontName, "cell", "单元格", "font", "字体", colName, xlsxInfoVos); +// +// } +// cursorsFontName.dispose(); +// } +// // 获取 charset 的 val 属性(字符集) +// try (XmlCursor cursorsFontCharset = cursorFonts.getObject().newCursor()){ +// cursorsFontCharset.selectPath(namespace + "./ns:charset"); +// if (cursorsFontCharset.toNextSelection()) { +// String fontCharset = cursorsFontCharset.getAttributeText(new QName("val")); +// addXlsxInfo(sheetName, "字体字符集", "ns:charset", fontCharset, "cell", "单元格", "font", "字体", colName, xlsxInfoVos); +// +// } +// cursorsFontCharset.dispose(); +// } +// // 获取 scheme 的 val 属性(字体方案) +// try (XmlCursor cursorsFontScheme = cursorFonts.getObject().newCursor()){ +// cursorsFontScheme.selectPath(namespace + "./ns:scheme"); +// if (cursorsFontScheme.toNextSelection()) { +// String fontScheme = cursorsFontScheme.getAttributeText(new QName("val")); +// addXlsxInfo(sheetName, "字体方案", "ns:scheme", fontScheme, "cell", "单元格", "font", "字体", colName, xlsxInfoVos); +// +// } +// cursorsFontScheme.dispose(); +// } +// break; +// } +// fontIndex ++; +// } +// cursorFonts.dispose(); +// } +// } +// // 背景颜色填充 +// if (fillId != null) { +// try (XmlCursor cursorFills = cursor.newCursor()) { +// if (!isCellStyle) { +// cursorFills.selectPath(namespace + "//ns:fills/ns:fill"); +// int fillIndex = 0; +// while (cursorFills.toNextSelection()) { +// if (fillIndex == Integer.parseInt(fillId)) { +// try (XmlCursor cursorsFill = cursorFills.getObject().newCursor()) { +// cursorsFill.selectPath(namespace + "./ns:patternFill"); +// if (cursorsFill.toNextSelection()) { +// // 获取 patternType 属性(填充样式) +// String patternType = cursorsFill.getAttributeText(new QName("patternType")); +// addXlsxInfo(sheetName, "填充样式", "ns:scheme/@theme", patternType, "cell", "单元格", "fill", "背景", colName, xlsxInfoVos); +// // 获取 fgColor 的 theme 和 tint 属性(填充颜色) +// try (XmlCursor cursorsFgColor = cursorsFill.getObject().newCursor()) { +// cursorsFgColor.selectPath(namespace + "./ns:fgColor"); +// if (cursorsFgColor.toNextSelection()) { +// String theme = cursorsFgColor.getAttributeText(new QName("theme")); +// String rgb = cursorsFgColor.getAttributeText(new QName("rgb")); +// addXlsxInfo(sheetName, "填充theme", "ns:scheme/@theme", theme, "cell", "单元格", "fill", "背景", colName, xlsxInfoVos); +// addXlsxInfo(sheetName, "填充颜色", "ns:fgColor/@rgb", rgb, "cell", "单元格", "fill", "背景", colName, xlsxInfoVos); +// } +// cursorsFgColor.dispose(); +// } +// // 获取 bgColor 的 indexed 属性(背景色) +// try (XmlCursor cursorsBgColor = cursorFills.getObject().newCursor()) { +// cursorsBgColor.selectPath(namespace + "./ns:bgColor"); +// if (cursorsBgColor.toNextSelection()) { +// String rgb = cursorsBgColor.getAttributeText(new QName("rgb")); +// addXlsxInfo(sheetName, "背景色", "ns:bgColor/@rgb", rgb, "cell", "单元格", "fill", "背景", colName, xlsxInfoVos); +// } +// cursorsBgColor.dispose(); +// } +// } +// } +// break; +// } +// fillIndex ++; +// } +// cursorFills.dispose(); +// } else { +// XmlCursor cursorDxf = cursorFills.newCursor(); +// cursorDxf.selectPath(namespace + "//ns:dxfs/ns:dxf"); +// int dxfIndex = 0; +// while (cursorDxf.toNextSelection()) { +// if (dxfIndex == dxfId) { +// XmlCursor fontXmlCursor = cursorDxf.getObject().newCursor(); +// fontXmlCursor.selectPath(namespace + "./ns:font/color/@rgb"); +// if (fontXmlCursor.toNextSelection()) { +// addXlsxInfo(sheetName, "文本颜色", "ns:color", fontXmlCursor.getTextValue(), "cell", "单元格", "font", "字体", colName, xlsxInfoVos); +// } +// fontXmlCursor.dispose(); +// XmlCursor fillXmlCursor = cursorDxf.getObject().newCursor(); +// fillXmlCursor.selectPath(namespace + "./ns:fill/ns:patternFill/ns:bgColor/@rgb"); +// if (fillXmlCursor.toNextSelection()) { +// addXlsxInfo(sheetName, "背景色", "ns:bgColor/@rgb", fillXmlCursor.getTextValue(), "cell", "单元格", "fill", "背景", colName, xlsxInfoVos); +// } +// fillXmlCursor.dispose(); +// } +// } +// } +// } +// } +// // 是否启用了边框设置 +// if (borderId != null) { +// try (XmlCursor cursorBorder = cursor.newCursor()) { +// cursorBorder.selectPath(namespace + "//ns:borders/ns:border"); +// int borderIndex = 0; +// while (cursorBorder.toNextSelection()) { +// if (borderIndex == Integer.parseInt(borderId)) { +// // 定义对角线边框。常用于带有斜线的单元格。如果 标签存在,表示对角线有边框,否则没有。 +// try (XmlCursor cursorsDiagonal = cursorBorder.getObject().newCursor()){ +// cursorsDiagonal.selectPath(namespace + "./ns:diagonal"); +// boolean isDiagonal = cursorsDiagonal.toNextSelection(); +// addXlsxInfo(sheetName, "斜线的单元格", "ns:diagonal", String.valueOf(isDiagonal), "cell", "单元格", "border", "边框", colName, xlsxInfoVos); +// cursorsDiagonal.dispose(); +// } +// // 获取上边框 +// try (XmlCursor cursorsTop = cursorBorder.getObject().newCursor()){ +// XmlCursor cursorsTops = cursorBorder.getObject().newCursor(); +// cursorsTops.selectPath(namespace + "./ns:top"); +// if (cursorsTops.toNextSelection()) { +// // 样式 +// String topStyle = cursorsTops.getAttributeText(new QName("style")); +// addXlsxInfo(sheetName, "上边框", "ns:top/@style", topStyle, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); +// +// } +// cursorsTops.selectPath(namespace + "./ns:color"); +// if (cursorsTops.toNextSelection()) { +// String topColor = cursorsTops.getAttributeText(new QName("rgb")); +// addXlsxInfo(sheetName, "上边框颜色", "ns:top/@rgb", topColor, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); +// +// } +// cursorsTops.dispose(); +// cursorsTop.dispose(); +// } +// // 获取下边框 +// try (XmlCursor cursorsBottom = cursorBorder.getObject().newCursor()){ +// XmlCursor cursorsBottoms = cursorBorder.getObject().newCursor(); +// cursorsBottoms.selectPath(namespace + "./ns:bottom"); +// if (cursorsBottoms.toNextSelection()) { +// // 样式 +// String bottomStyle = cursorsBottoms.getAttributeText(new QName("style")); +// addXlsxInfo(sheetName, "下边框", "ns:top/@rgb", bottomStyle, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); +// +// } +// // 颜色 +// cursorsBottoms.selectPath(namespace + "./ns:color"); +// if (cursorsBottoms.toNextSelection()) { +// String bottomColor = cursorsBottoms.getAttributeText(new QName("rgb")); +// addXlsxInfo(sheetName, "下边框颜色", "ns:top/@rgb", bottomColor, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); +// +// } +// cursorsBottoms.dispose(); +// cursorsBottom.dispose(); +// } +// // 获取左边框 +// try (XmlCursor cursorsLeft = cursorBorder.getObject().newCursor()){ +// XmlCursor cursorsLefts = cursorBorder.getObject().newCursor(); +// cursorsLefts.selectPath(namespace + "./ns:left"); +// if (cursorsLefts.toNextSelection()) { +// // 样式 +// String leftStyle = cursorsLefts.getAttributeText(new QName("style")); +// addXlsxInfo(sheetName, "左边框", "ns:top/@rgb", leftStyle, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); +// } +// // 颜色 +// cursorsLefts.selectPath(namespace + "./ns:color"); +// if (cursorsLefts.toNextSelection()) { +// String leftColor = cursorsLefts.getAttributeText(new QName("rgb")); +// addXlsxInfo(sheetName, "左边框颜色", "ns:top/@rgb", leftColor, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); +// +// } +// cursorsLefts.dispose(); +// cursorsLeft.dispose(); +// } +// // 获取右边框 +// try (XmlCursor cursorsRight = cursorBorder.getObject().newCursor()){ +// XmlCursor cursorsRights = cursorBorder.getObject().newCursor(); +// cursorsRights.selectPath(namespace + "./ns:right"); +// if (cursorsRights.toNextSelection()) { +// // 样式 +// String rightStyle = cursorsRights.getAttributeText(new QName("style")); +// addXlsxInfo(sheetName, "右边框", "ns:top/@rgb", rightStyle, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); +// +// } +// // 颜色 +// cursorsRights.selectPath(namespace + "./ns:color"); +// if (cursorsRights.toNextSelection()) { +// String rightColor = cursorsRights.getAttributeText(new QName("rgb")); +// addXlsxInfo(sheetName, "右边框颜色", "ns:top/@rgb", rightColor, "cell", "单元格", "border", "边框", colName, xlsxInfoVos); +// } +// cursorsRights.dispose(); +// cursorsRight.dispose(); +// } +// break; +// } +// borderIndex ++; +// } +// cursorBorder.dispose(); +// } +// } +// return cursor; +// } +// +// public static XmlCursor extractStyleXml(String excelFilePath) throws Exception { +// // 解压 Excel 文件并读取 sharedStrings.xml +// ZipFile zipFile = new ZipFile(excelFilePath); +// // 找到 sharedStrings.xml 文件的路径 +// ZipEntry sharedStringsEntry = zipFile.getEntry("xl/styles.xml"); +// +// // 如果找不到 sharedStrings.xml,则返回空数组 +// if (sharedStringsEntry == null) { +// zipFile.close(); +// return null; +// } +// +// // 读取 sharedStrings.xml 文件 +// InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); +// byte[] content = inputStream.readAllBytes(); +// String xmlContent = new String(content); +// // 使用 XmlObject 解析 sharedStrings.xml +// XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); +// XmlCursor cursor = xmlObject.newCursor(); +// zipFile.close(); // 关闭 zip 文件 +// return cursor; +// } +// +// public static XmlCursor extractConnectionsXml(String excelFilePath) throws Exception { +// // 解压 Excel 文件并读取 sharedStrings.xml +// ZipFile zipFile = new ZipFile(excelFilePath); +// // 找到 sharedStrings.xml 文件的路径 +// ZipEntry sharedStringsEntry = zipFile.getEntry("xl/connections.xml"); +// +// // 如果找不到 sharedStrings.xml,则返回空数组 +// if (sharedStringsEntry == null) { +// zipFile.close(); +// return null; +// } +// +// // 读取 sharedStrings.xml 文件 +// InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); +// byte[] content = inputStream.readAllBytes(); +// String xmlContent = new String(content); +// // 使用 XmlObject 解析 sharedStrings.xml +// XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); +// XmlCursor cursor = xmlObject.newCursor(); +// zipFile.close(); // 关闭 zip 文件 +// return cursor; +// } +// +//// public static String getDrawingInfo(String excelFilePath) throws Exception { +//// // 解压 Excel 文件并读取 sharedStrings.xml +//// ZipFile zipFile = new ZipFile(excelFilePath); +//// Enumeration entries = zipFile.entries(); +//// while (entries.hasMoreElements()) { +//// ZipEntry entry = entries.nextElement(); +//// String entryName = entry.getName(); +//// // 1、获取sheet*.xml.rels下面的文件 +//// if (entryName.startsWith("xl/worksheets/_rels") && entryName.endsWith(".xml.rels")) { +//// XlsxDrawingSheetVo xlsxDrawingSheetVo = new XlsxDrawingSheetVo(); +//// // 读取数据 +//// ZipEntry sharedStringsEntry = zipFile.getEntry(entryName); +//// InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); +//// byte[] content = inputStream.readAllBytes(); +//// String xmlContent = new String(content); +//// // 使用 XmlObject 解析 sharedStrings.xml +//// XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); +//// XmlCursor sheetCursor = xmlObject.newCursor(); +//// // 正则匹配:提取连续的数字 +//// StringBuilder numbers = new StringBuilder(); +//// for (char c : entryName.toCharArray()) { +//// // 检查是否是数字 +//// if (Character.isDigit(c)) { +//// numbers.append(c); +//// } +//// } +//// // 第几个sheet对应的索引 +//// int number = Integer.parseInt(numbers.toString()); +//// xlsxDrawingSheetVo.setSheetNumber(String.valueOf(number)); +//// sheetCursor.selectPath("declare namespace r='http://schemas.openxmlformats.org/package/2006/relationships' .//r:Relationships/r:Relationship"); +//// while (sheetCursor.toNextSelection()) { +//// // 2、开始获取内容 +//// // 2-1、获取ID +//// String id = sheetCursor.getAttributeText(new QName("Id")); +//// // 2-2、获取文件路径 +//// String target = sheetCursor.getAttributeText(new QName("Target")); +//// // 3、在往下获取对应的文件,及文件路径 +//// // 进行路径字符串替换 .. -> xl +//// String newTarget = target.replace("..", "xl"); +//// System.out.println("newTarget = " + newTarget); +//// ZipEntry sharedStringsEntry2 = zipFile.getEntry(newTarget); +//// InputStream inputStream2 = zipFile.getInputStream(sharedStringsEntry2); +//// byte[] content2 = inputStream2.readAllBytes(); +//// String xmlContent2 = new String(content2); +//// // 使用 XmlObject 解析 sharedStrings.xml +//// XmlObject xmlObject2 = XmlObject.Factory.parse(xmlContent2); +//// XmlCursor sheetCursor2 = xmlObject2.newCursor(); +//// // 4、判断是否存在对应文件的_rels * 文件 +//// // 路径自定义 xl/drawings/drawing1.xml +//// // 分割字符串 +//// String[] split = newTarget.split("/"); +//// String newRelsFilePath = split[0]+"/"+split[1]+"/_rels/"+split[2]+".rels"; +//// // 在进行获取数据,获取文件路径 +//// ZipEntry sharedStringsEntry3 = zipFile.getEntry(newRelsFilePath); +//// if (sharedStringsEntry3 != null) { +//// InputStream inputStream3 = zipFile.getInputStream(sharedStringsEntry3); +//// byte[] content3 = inputStream3.readAllBytes(); +//// String xmlContent3 = new String(content3); +//// // 使用 XmlObject 解析 sharedStrings.xml +//// XmlObject xmlObject3 = XmlObject.Factory.parse(xmlContent3); +//// XmlCursor sheetCursor3 = xmlObject3.newCursor(); +//// sheetCursor3.selectPath("declare namespace r='http://schemas.openxmlformats.org/package/2006/relationships' .//r:Relationships/r:Relationship"); +//// while (sheetCursor3.toNextSelection()) { +//// // 2、开始获取内容 +//// // 2-1、获取ID +//// String id2 = sheetCursor3.getAttributeText(new QName("Id")); +//// // 2-2、获取文件路径 +//// String target2 = sheetCursor3.getAttributeText(new QName("Target")); +//// // 3、在往下获取对应的文件,及文件路径 +//// System.out.println("target2 = " + target2); +//// // 进行路径字符串替换 .. -> xl +//// String newTarget2 = target2.replace("..", "xl"); +//// } +//// } +//// +//// } +//// } +//// } +//// zipFile.close(); // 关闭 zip 文件 +//// return ""; +//// } +// +// public static String getDrawingInfos(String excelFilePath) throws Exception { +// try (ZipFile zipFile = new ZipFile(excelFilePath)) { +// Enumeration entries = zipFile.entries(); +// +// while (entries.hasMoreElements()) { +// ZipEntry entry = entries.nextElement(); +// String entryName = entry.getName(); +// +// if (entryName.startsWith("xl/worksheets/_rels") && entryName.endsWith(".xml.rels")) { +// String xmlContent = readZipEntry(zipFile, entryName); +// XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); +// XmlCursor cursor = xmlObject.newCursor(); +// +// // 正则匹配:提取连续的数字 +// StringBuilder numbers = new StringBuilder(); +// for (char c : entryName.toCharArray()) { +// // 检查是否是数字 +// if (Character.isDigit(c)) { +// numbers.append(c); +// } +// } +// // 第几个sheet对应的索引 +// int number = Integer.parseInt(numbers.toString()); +// List drawingVOS = new ArrayList<>(); +// cursor.selectPath("declare namespace r='http://schemas.openxmlformats.org/package/2006/relationships' .//r:Relationships/r:Relationship"); +// while (cursor.toNextSelection()) { +// // 2、开始获取内容 +// XlsxDrawingSheetVo xlsxDrawingSheetVo = new XlsxDrawingSheetVo(); +// String rId = cursor.getAttributeText(new QName("Id")); +// String target = cursor.getAttributeText(new QName("Target")); +// String nextPath = target.replace("..", "xl"); +// xlsxDrawingSheetVo.setSheetNumber(String.valueOf(number)); +// xlsxDrawingSheetVo.setRId(rId); +// traverseRels(zipFile, nextPath, xlsxDrawingSheetVo, String.valueOf(number), drawingVOS); +// } +// drawingSheetVOS.add(drawingVOS); +// } +// } +// } +// return ""; +// } +// // 递归遍历 _rels 下级文件 +// private static void traverseRels(ZipFile zipFile, String path, XlsxDrawingSheetVo xlsxDrawingSheetVo, String sheetName, List drawingVOS) throws Exception { +// if (path == null || path.isEmpty()) { +// return; +// } +// // 1、获取对应文件内容 +// String content = readZipEntry(zipFile, path); +// // 文件不存在,终止链 +// if (content == null) { +// return; +// } +// XmlObject xmlObject = XmlObject.Factory.parse(content); +// XmlCursor cursor = xmlObject.newCursor(); +// xlsxDrawingSheetVo.setXmlCursor(cursor); +//// System.out.println(cursor.xmlText()); +// // 生成对应的 .rels 路径 +// String[] parts = path.split("/"); +// String relsPath = parts[0] + "/" + parts[1] + "/_rels/" + parts[2] + ".rels"; +// xlsxDrawingSheetVo.setTypeName(path); +// drawingVOS.add(xlsxDrawingSheetVo); +// String contents = readZipEntry(zipFile, relsPath); +// // 文件不存在,终止链 +// if (contents == null) { +// return; +// } +// XmlObject xmlObjects = XmlObject.Factory.parse(contents); +// XmlCursor cursors = xmlObjects.newCursor(); +// cursors.selectPath("declare namespace r='http://schemas.openxmlformats.org/package/2006/relationships' .//r:Relationships/r:Relationship"); +// // 2、开始获取内容 +// while (cursors.toNextSelection()) { +//// System.out.println(cursors.xmlText()); +// XlsxDrawingSheetVo xlsxDrawingSheetVos = new XlsxDrawingSheetVo(); +// String target = cursors.getAttributeText(new QName("Target")); +// String rId = cursors.getAttributeText(new QName("Id")); +// xlsxDrawingSheetVos.setRId(rId); +// xlsxDrawingSheetVos.setSheetNumber(sheetName); +// xlsxDrawingSheetVos.setRId(rId); +// if (target == null) { +// continue; +// } +// String newPath = ""; +// if (!target.contains("./")) { +// // 如果没有包含路径,可能是在原本的路径下面 +// newPath = parts[0] + "/" + parts[1] + "/" + target; +// } else { +// newPath = target.replace("..", "xl"); +// } +// +//// System.out.println("Found path: " + newPath); +// // 递归继续查找下一级 +// if (zipFile.getEntry(relsPath) != null) { +// traverseRels(zipFile, newPath, xlsxDrawingSheetVos, sheetName, drawingVOS); +// } +// } +// } +// // 工具方法:从 zip 文件中读取条目内容 +// private static String readZipEntry(ZipFile zipFile, String entryName) throws IOException { +// ZipEntry entry = zipFile.getEntry(entryName); +// if (entry == null) { +// return null; +// } +// try (InputStream is = zipFile.getInputStream(entry)) { +// return new String(is.readAllBytes()); +// } +// } +// +// +// public static List extractChartXml(String excelFilePath) throws Exception { +// List xlsxCharVos = new ArrayList<>(); +// // 解压 Excel 文件并读取 sharedStrings.xml +// ZipFile zipFile = new ZipFile(excelFilePath); +// // Enumeration entries = zipFile.entries(); // while (entries.hasMoreElements()) { // ZipEntry entry = entries.nextElement(); // String entryName = entry.getName(); -// // 1、获取sheet*.xml.rels下面的文件 -// if (entryName.startsWith("xl/worksheets/_rels") && entryName.endsWith(".xml.rels")) { -// XlsxDrawingSheetVo xlsxDrawingSheetVo = new XlsxDrawingSheetVo(); +// // 检查是否属于 xl/charts/ 目录下的图表文件 +// if (entryName.startsWith("xl/charts/chart") && entryName.endsWith(".xml")) { // // 读取数据 // ZipEntry sharedStringsEntry = zipFile.getEntry(entryName); // InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); @@ -920,7 +1111,7 @@ public class WpsExcelUtils { // String xmlContent = new String(content); // // 使用 XmlObject 解析 sharedStrings.xml // XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); -// XmlCursor sheetCursor = xmlObject.newCursor(); +// XmlCursor cursor = xmlObject.newCursor(); // // 正则匹配:提取连续的数字 // StringBuilder numbers = new StringBuilder(); // for (char c : entryName.toCharArray()) { @@ -929,308 +1120,117 @@ public class WpsExcelUtils { // numbers.append(c); // } // } -// // 第几个sheet对应的索引 // int number = Integer.parseInt(numbers.toString()); -// xlsxDrawingSheetVo.setSheetNumber(String.valueOf(number)); -// sheetCursor.selectPath("declare namespace r='http://schemas.openxmlformats.org/package/2006/relationships' .//r:Relationships/r:Relationship"); -// while (sheetCursor.toNextSelection()) { -// // 2、开始获取内容 -// // 2-1、获取ID -// String id = sheetCursor.getAttributeText(new QName("Id")); -// // 2-2、获取文件路径 -// String target = sheetCursor.getAttributeText(new QName("Target")); -// // 3、在往下获取对应的文件,及文件路径 -// // 进行路径字符串替换 .. -> xl -// String newTarget = target.replace("..", "xl"); -// System.out.println("newTarget = " + newTarget); -// ZipEntry sharedStringsEntry2 = zipFile.getEntry(newTarget); -// InputStream inputStream2 = zipFile.getInputStream(sharedStringsEntry2); -// byte[] content2 = inputStream2.readAllBytes(); -// String xmlContent2 = new String(content2); -// // 使用 XmlObject 解析 sharedStrings.xml -// XmlObject xmlObject2 = XmlObject.Factory.parse(xmlContent2); -// XmlCursor sheetCursor2 = xmlObject2.newCursor(); -// // 4、判断是否存在对应文件的_rels * 文件 -// // 路径自定义 xl/drawings/drawing1.xml -// // 分割字符串 -// String[] split = newTarget.split("/"); -// String newRelsFilePath = split[0]+"/"+split[1]+"/_rels/"+split[2]+".rels"; -// // 在进行获取数据,获取文件路径 -// ZipEntry sharedStringsEntry3 = zipFile.getEntry(newRelsFilePath); -// if (sharedStringsEntry3 != null) { -// InputStream inputStream3 = zipFile.getInputStream(sharedStringsEntry3); -// byte[] content3 = inputStream3.readAllBytes(); -// String xmlContent3 = new String(content3); -// // 使用 XmlObject 解析 sharedStrings.xml -// XmlObject xmlObject3 = XmlObject.Factory.parse(xmlContent3); -// XmlCursor sheetCursor3 = xmlObject3.newCursor(); -// sheetCursor3.selectPath("declare namespace r='http://schemas.openxmlformats.org/package/2006/relationships' .//r:Relationships/r:Relationship"); -// while (sheetCursor3.toNextSelection()) { -// // 2、开始获取内容 -// // 2-1、获取ID -// String id2 = sheetCursor3.getAttributeText(new QName("Id")); -// // 2-2、获取文件路径 -// String target2 = sheetCursor3.getAttributeText(new QName("Target")); -// // 3、在往下获取对应的文件,及文件路径 -// System.out.println("target2 = " + target2); -// // 进行路径字符串替换 .. -> xl -// String newTarget2 = target2.replace("..", "xl"); -// } +// // 如果列表为空,则创建新的xlsxCharVO对象 +// // 如果列表不为空,则检查最后一个元素的count是否等于当前数字 +// Optional result = xlsxCharVos.stream().filter(xlsxCharVO -> number == xlsxCharVO.getCount()).findFirst(); +// if (result.isEmpty()) { +// // 创建新的xlsxCharVO对象 +// XlsxCharVO xlsxCharVO = new XlsxCharVO(); +// xlsxCharVO.setCount(number); +// xlsxCharVO.setChars(cursor); +// xlsxCharVos.add(xlsxCharVO); +// } else { +// XlsxCharVO lastXlsxCharVO = result.get(); +// lastXlsxCharVO.setChars(cursor); +// xlsxCharVos.removeIf(xlsxCharVO -> number == xlsxCharVO.getCount()); +// xlsxCharVos.add(lastXlsxCharVO); +// } +// } +// if (entryName.startsWith("xl/charts/style") && entryName.endsWith(".xml")) { +// // 读取数据 +// ZipEntry sharedStringsEntry = zipFile.getEntry(entryName); +// InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); +// byte[] content = inputStream.readAllBytes(); +// String xmlContent = new String(content); +// // 使用 XmlObject 解析 sharedStrings.xml +// XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); +// XmlCursor cursor = xmlObject.newCursor(); +// // 正则匹配:提取连续的数字 +// StringBuilder numbers = new StringBuilder(); +// for (char c : entryName.toCharArray()) { +// // 检查是否是数字 +// if (Character.isDigit(c)) { +// numbers.append(c); // } -// +// } +// int number = Integer.parseInt(numbers.toString()); +// // 如果列表为空,则创建新的xlsxCharVO对象 +// // 如果列表不为空,则检查最后一个元素的count是否等于当前数字 +// Optional result = xlsxCharVos.stream().filter(xlsxCharVO -> number == xlsxCharVO.getCount()).findFirst(); +// if (result.isEmpty()) { +// // 创建新的xlsxCharVO对象 +// XlsxCharVO xlsxCharVO = new XlsxCharVO(); +// xlsxCharVO.setCount(number); +// xlsxCharVO.setStyle(cursor); +// xlsxCharVos.add(xlsxCharVO); +// } else { +// XlsxCharVO lastXlsxCharVO = result.get(); +// lastXlsxCharVO.setStyle(cursor); +// xlsxCharVos.removeIf(xlsxCharVO -> number == xlsxCharVO.getCount()); +// xlsxCharVos.add(lastXlsxCharVO); +// } +// } +// if (entryName.startsWith("xl/charts/color") && entryName.endsWith(".xml")) { +// // 读取数据 +// ZipEntry sharedStringsEntry = zipFile.getEntry(entryName); +// InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); +// byte[] content = inputStream.readAllBytes(); +// String xmlContent = new String(content); +// // 使用 XmlObject 解析 sharedStrings.xml +// XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); +// XmlCursor cursor = xmlObject.newCursor(); +// // 正则匹配:提取连续的数字 +// StringBuilder numbers = new StringBuilder(); +// for (char c : entryName.toCharArray()) { +// // 检查是否是数字 +// if (Character.isDigit(c)) { +// numbers.append(c); +// } +// } +// int number = Integer.parseInt(numbers.toString()); +// // 如果列表为空,则创建新的xlsxCharVO对象 +// // 如果列表不为空,则检查最后一个元素的count是否等于当前数字 +// Optional result = xlsxCharVos.stream().filter(xlsxCharVO -> number == xlsxCharVO.getCount()).findFirst(); +// if (result.isEmpty()) { +// // 创建新的xlsxCharVO对象 +// XlsxCharVO xlsxCharVO = new XlsxCharVO(); +// xlsxCharVO.setCount(number); +// xlsxCharVO.setColors(cursor); +// xlsxCharVos.add(xlsxCharVO); +// } else { +// XlsxCharVO lastXlsxCharVO = result.get(); +// lastXlsxCharVO.setColors(cursor); +// xlsxCharVos.removeIf(xlsxCharVO -> number == xlsxCharVO.getCount()); +// xlsxCharVos.add(lastXlsxCharVO); // } // } // } // zipFile.close(); // 关闭 zip 文件 -// return ""; +// return xlsxCharVos; // } - - public static String getDrawingInfos(String excelFilePath) throws Exception { - try (ZipFile zipFile = new ZipFile(excelFilePath)) { - Enumeration entries = zipFile.entries(); - - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - String entryName = entry.getName(); - - if (entryName.startsWith("xl/worksheets/_rels") && entryName.endsWith(".xml.rels")) { - String xmlContent = readZipEntry(zipFile, entryName); - XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); - XmlCursor cursor = xmlObject.newCursor(); - - // 正则匹配:提取连续的数字 - StringBuilder numbers = new StringBuilder(); - for (char c : entryName.toCharArray()) { - // 检查是否是数字 - if (Character.isDigit(c)) { - numbers.append(c); - } - } - // 第几个sheet对应的索引 - int number = Integer.parseInt(numbers.toString()); - List drawingVOS = new ArrayList<>(); - cursor.selectPath("declare namespace r='http://schemas.openxmlformats.org/package/2006/relationships' .//r:Relationships/r:Relationship"); - while (cursor.toNextSelection()) { - // 2、开始获取内容 - XlsxDrawingSheetVo xlsxDrawingSheetVo = new XlsxDrawingSheetVo(); - String rId = cursor.getAttributeText(new QName("Id")); - String target = cursor.getAttributeText(new QName("Target")); - String nextPath = target.replace("..", "xl"); - xlsxDrawingSheetVo.setSheetNumber(String.valueOf(number)); - xlsxDrawingSheetVo.setRId(rId); - traverseRels(zipFile, nextPath, xlsxDrawingSheetVo, String.valueOf(number), drawingVOS); - } - drawingSheetVOS.add(drawingVOS); - } - } - } - return ""; - } - // 递归遍历 _rels 下级文件 - private static void traverseRels(ZipFile zipFile, String path, XlsxDrawingSheetVo xlsxDrawingSheetVo, String sheetName, List drawingVOS) throws Exception { - if (path == null || path.isEmpty()) { - return; - } - // 1、获取对应文件内容 - String content = readZipEntry(zipFile, path); - // 文件不存在,终止链 - if (content == null) { - return; - } - XmlObject xmlObject = XmlObject.Factory.parse(content); - XmlCursor cursor = xmlObject.newCursor(); - xlsxDrawingSheetVo.setXmlCursor(cursor); -// System.out.println(cursor.xmlText()); - // 生成对应的 .rels 路径 - String[] parts = path.split("/"); - String relsPath = parts[0] + "/" + parts[1] + "/_rels/" + parts[2] + ".rels"; - xlsxDrawingSheetVo.setTypeName(path); - drawingVOS.add(xlsxDrawingSheetVo); - String contents = readZipEntry(zipFile, relsPath); - // 文件不存在,终止链 - if (contents == null) { - return; - } - XmlObject xmlObjects = XmlObject.Factory.parse(contents); - XmlCursor cursors = xmlObjects.newCursor(); - cursors.selectPath("declare namespace r='http://schemas.openxmlformats.org/package/2006/relationships' .//r:Relationships/r:Relationship"); - // 2、开始获取内容 - while (cursors.toNextSelection()) { -// System.out.println(cursors.xmlText()); - XlsxDrawingSheetVo xlsxDrawingSheetVos = new XlsxDrawingSheetVo(); - String target = cursors.getAttributeText(new QName("Target")); - String rId = cursors.getAttributeText(new QName("Id")); - xlsxDrawingSheetVos.setRId(rId); - xlsxDrawingSheetVos.setSheetNumber(sheetName); - xlsxDrawingSheetVos.setRId(rId); - if (target == null) { - continue; - } - String newPath = ""; - if (!target.contains("./")) { - // 如果没有包含路径,可能是在原本的路径下面 - newPath = parts[0] + "/" + parts[1] + "/" + target; - } else { - newPath = target.replace("..", "xl"); - } - -// System.out.println("Found path: " + newPath); - // 递归继续查找下一级 - if (zipFile.getEntry(relsPath) != null) { - traverseRels(zipFile, newPath, xlsxDrawingSheetVos, sheetName, drawingVOS); - } - } - } - // 工具方法:从 zip 文件中读取条目内容 - private static String readZipEntry(ZipFile zipFile, String entryName) throws IOException { - ZipEntry entry = zipFile.getEntry(entryName); - if (entry == null) { - return null; - } - try (InputStream is = zipFile.getInputStream(entry)) { - return new String(is.readAllBytes()); - } - } - - - public static List extractChartXml(String excelFilePath) throws Exception { - List xlsxCharVos = new ArrayList<>(); - // 解压 Excel 文件并读取 sharedStrings.xml - ZipFile zipFile = new ZipFile(excelFilePath); - - Enumeration entries = zipFile.entries(); - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - String entryName = entry.getName(); - // 检查是否属于 xl/charts/ 目录下的图表文件 - if (entryName.startsWith("xl/charts/chart") && entryName.endsWith(".xml")) { - // 读取数据 - ZipEntry sharedStringsEntry = zipFile.getEntry(entryName); - InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); - byte[] content = inputStream.readAllBytes(); - String xmlContent = new String(content); - // 使用 XmlObject 解析 sharedStrings.xml - XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); - XmlCursor cursor = xmlObject.newCursor(); - // 正则匹配:提取连续的数字 - StringBuilder numbers = new StringBuilder(); - for (char c : entryName.toCharArray()) { - // 检查是否是数字 - if (Character.isDigit(c)) { - numbers.append(c); - } - } - int number = Integer.parseInt(numbers.toString()); - // 如果列表为空,则创建新的xlsxCharVO对象 - // 如果列表不为空,则检查最后一个元素的count是否等于当前数字 - Optional result = xlsxCharVos.stream().filter(xlsxCharVO -> number == xlsxCharVO.getCount()).findFirst(); - if (result.isEmpty()) { - // 创建新的xlsxCharVO对象 - XlsxCharVO xlsxCharVO = new XlsxCharVO(); - xlsxCharVO.setCount(number); - xlsxCharVO.setChars(cursor); - xlsxCharVos.add(xlsxCharVO); - } else { - XlsxCharVO lastXlsxCharVO = result.get(); - lastXlsxCharVO.setChars(cursor); - xlsxCharVos.removeIf(xlsxCharVO -> number == xlsxCharVO.getCount()); - xlsxCharVos.add(lastXlsxCharVO); - } - } - if (entryName.startsWith("xl/charts/style") && entryName.endsWith(".xml")) { - // 读取数据 - ZipEntry sharedStringsEntry = zipFile.getEntry(entryName); - InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); - byte[] content = inputStream.readAllBytes(); - String xmlContent = new String(content); - // 使用 XmlObject 解析 sharedStrings.xml - XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); - XmlCursor cursor = xmlObject.newCursor(); - // 正则匹配:提取连续的数字 - StringBuilder numbers = new StringBuilder(); - for (char c : entryName.toCharArray()) { - // 检查是否是数字 - if (Character.isDigit(c)) { - numbers.append(c); - } - } - int number = Integer.parseInt(numbers.toString()); - // 如果列表为空,则创建新的xlsxCharVO对象 - // 如果列表不为空,则检查最后一个元素的count是否等于当前数字 - Optional result = xlsxCharVos.stream().filter(xlsxCharVO -> number == xlsxCharVO.getCount()).findFirst(); - if (result.isEmpty()) { - // 创建新的xlsxCharVO对象 - XlsxCharVO xlsxCharVO = new XlsxCharVO(); - xlsxCharVO.setCount(number); - xlsxCharVO.setStyle(cursor); - xlsxCharVos.add(xlsxCharVO); - } else { - XlsxCharVO lastXlsxCharVO = result.get(); - lastXlsxCharVO.setStyle(cursor); - xlsxCharVos.removeIf(xlsxCharVO -> number == xlsxCharVO.getCount()); - xlsxCharVos.add(lastXlsxCharVO); - } - } - if (entryName.startsWith("xl/charts/color") && entryName.endsWith(".xml")) { - // 读取数据 - ZipEntry sharedStringsEntry = zipFile.getEntry(entryName); - InputStream inputStream = zipFile.getInputStream(sharedStringsEntry); - byte[] content = inputStream.readAllBytes(); - String xmlContent = new String(content); - // 使用 XmlObject 解析 sharedStrings.xml - XmlObject xmlObject = XmlObject.Factory.parse(xmlContent); - XmlCursor cursor = xmlObject.newCursor(); - // 正则匹配:提取连续的数字 - StringBuilder numbers = new StringBuilder(); - for (char c : entryName.toCharArray()) { - // 检查是否是数字 - if (Character.isDigit(c)) { - numbers.append(c); - } - } - int number = Integer.parseInt(numbers.toString()); - // 如果列表为空,则创建新的xlsxCharVO对象 - // 如果列表不为空,则检查最后一个元素的count是否等于当前数字 - Optional result = xlsxCharVos.stream().filter(xlsxCharVO -> number == xlsxCharVO.getCount()).findFirst(); - if (result.isEmpty()) { - // 创建新的xlsxCharVO对象 - XlsxCharVO xlsxCharVO = new XlsxCharVO(); - xlsxCharVO.setCount(number); - xlsxCharVO.setColors(cursor); - xlsxCharVos.add(xlsxCharVO); - } else { - XlsxCharVO lastXlsxCharVO = result.get(); - lastXlsxCharVO.setColors(cursor); - xlsxCharVos.removeIf(xlsxCharVO -> number == xlsxCharVO.getCount()); - xlsxCharVos.add(lastXlsxCharVO); - } - } - } - zipFile.close(); // 关闭 zip 文件 - return xlsxCharVos; - } - - - public static String getNamespace(String xmlText) { - // 1-1、创建最全的命名空间 - Pattern pattern = Pattern.compile("xmlns:(\\w+)=\"([^\"]+)\""); - Matcher matcher = pattern.matcher(xmlText); - Map namespaces = new HashMap<>(); - while (matcher.find()) { - String prefix = matcher.group(1); - String uri = matcher.group(2); - namespaces.put(prefix, uri); - } - StringBuilder xpathBuilder = new StringBuilder(); - namespaces.forEach((prefix, uri) -> - xpathBuilder.append("declare namespace ") - .append(prefix) - .append("='") - .append(uri) - .append("' ") - ); - // 2-1、获取出来最全的命名空间 - String allPathx = xpathBuilder.toString(); - return allPathx; - } -} +// +// +// public static String getNamespace(String xmlText) { +// // 1-1、创建最全的命名空间 +// Pattern pattern = Pattern.compile("xmlns:(\\w+)=\"([^\"]+)\""); +// Matcher matcher = pattern.matcher(xmlText); +// Map namespaces = new HashMap<>(); +// while (matcher.find()) { +// String prefix = matcher.group(1); +// String uri = matcher.group(2); +// namespaces.put(prefix, uri); +// } +// StringBuilder xpathBuilder = new StringBuilder(); +// namespaces.forEach((prefix, uri) -> +// xpathBuilder.append("declare namespace ") +// .append(prefix) +// .append("='") +// .append(uri) +// .append("' ") +// ); +// // 2-1、获取出来最全的命名空间 +// String allPathx = xpathBuilder.toString(); +// return allPathx; +// } +//} diff --git a/src/main/java/com/example/exam/exam/service/wpspptx/pptx4j/SlideConversion.java b/src/main/java/com/example/exam/exam/service/wpspptx/pptx4j/SlideConversion.java index 4ee3755..357e566 100644 --- a/src/main/java/com/example/exam/exam/service/wpspptx/pptx4j/SlideConversion.java +++ b/src/main/java/com/example/exam/exam/service/wpspptx/pptx4j/SlideConversion.java @@ -1,10 +1,10 @@ package com.example.exam.exam.service.wpspptx.pptx4j; +import com.example.exam.exam.service.wpspptx.pptx4j.vo.SlideDataInfoVO; import org.apache.poi.xslf.usermodel.XMLSlideShow; import org.apache.poi.xslf.usermodel.XSLFSlide; import org.apache.xmlbeans.XmlCursor; import org.springframework.web.multipart.MultipartFile; -import pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j.vo.SlideDataInfoVO; import java.io.InputStream; import java.util.ArrayList;