【新增】 ppt考点信息等
This commit is contained in:
@@ -5,12 +5,14 @@ import jakarta.xml.bind.JAXBException;
|
||||
import org.docx4j.dml.*;
|
||||
import org.docx4j.jaxb.XPathBinderAssociationIsPartialException;
|
||||
import org.pptx4j.pml.*;
|
||||
import pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j.utils.HexColorUtils;
|
||||
import pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j.utils.PtToCmConverter;
|
||||
import pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j.utils.PtToEmuConverter;
|
||||
import pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j.utils.Transition;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ShapePage {
|
||||
|
||||
@@ -453,6 +455,7 @@ public class ShapePage {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getAniationInfo(List<Object> objects, List<Object> upObjects, String spId, String parameter) {
|
||||
boolean isDur = false;
|
||||
boolean isDirection = false;
|
||||
@@ -466,7 +469,34 @@ public class ShapePage {
|
||||
// 判断方向
|
||||
if (isDirection) {
|
||||
if (object instanceof CTTLAnimateEffectBehavior) {
|
||||
return ((CTTLAnimateEffectBehavior) object).getFilter();
|
||||
return Transition.effectWithDirToChinese(((CTTLAnimateEffectBehavior) object).getFilter());
|
||||
} else {
|
||||
// 获取行动轨迹
|
||||
for (Object ob : objects) {
|
||||
if (ob instanceof CTTLAnimateBehavior) {
|
||||
List<CTTLTimeAnimateValue> cttlTimeAnimateValues = ((CTTLAnimateBehavior) ob).getTavLst().getTav();
|
||||
for (CTTLTimeAnimateValue cttlTimeAnimateValue : cttlTimeAnimateValues) {
|
||||
String value = cttlTimeAnimateValue.getVal().getStrVal().getVal();
|
||||
if (cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("0-#ppt_h/") ||
|
||||
cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("-#ppt_h")) {
|
||||
return "自顶部";
|
||||
}
|
||||
if (cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("#ppt_h+") ||
|
||||
cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("+#ppt_h")) {
|
||||
return "自底部";
|
||||
}
|
||||
if (cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("+#ppt_w") ||
|
||||
cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("#ppt_w+")) {
|
||||
return "自右侧";
|
||||
}
|
||||
if (cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("0-#ppt_w/") ||
|
||||
cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("-#ppt_w") ||
|
||||
cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("-N")) {
|
||||
return "自左侧";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (object instanceof CTTLSetBehavior) {
|
||||
@@ -828,7 +858,7 @@ public class ShapePage {
|
||||
// 遍历段落中的所有文本运行
|
||||
Object obj = paragraph.getEGTextRun().get(0);
|
||||
if (obj instanceof CTRegularTextRun ctRegularTextRun) {
|
||||
return ctRegularTextRun.getRPr().getSolidFill().getSrgbClr().getVal();
|
||||
return HexColorUtils.hexToColorString(ctRegularTextRun.getRPr().getSolidFill().getSrgbClr().getVal());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -11,6 +11,37 @@ import java.util.List;
|
||||
|
||||
public class ShapePic {
|
||||
|
||||
// 图片 插入
|
||||
public static String getAddPic(Pic sp, CTSlideTiming timing) {
|
||||
return "是";
|
||||
}
|
||||
|
||||
// 自选图形 - 类型
|
||||
public static String getShapeType(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties ctShapeProperties = sp.getSpPr();
|
||||
CTPresetGeometry2D prst = ctShapeProperties.getPrstGeom();
|
||||
if (prst != null && prst.getPrst() != null) {
|
||||
STShapeType t = prst.getPrst();
|
||||
switch (t) {
|
||||
case HEXAGON: return "六边形";
|
||||
case RECT: return "矩形";
|
||||
case ROUND_RECT: return "圆角矩形";
|
||||
case ELLIPSE: return "椭圆";
|
||||
case TRIANGLE: return "三角形";
|
||||
case DIAMOND: return "菱形";
|
||||
case PARALLELOGRAM: return "平行四边形";
|
||||
case TRAPEZOID: return "梯形";
|
||||
case OCTAGON: return "八边形";
|
||||
case PENTAGON: return "五边形";
|
||||
default: return "预设形状:" + t.value();
|
||||
}
|
||||
}
|
||||
if (ctShapeProperties.getCustGeom() != null) {
|
||||
return "自定义几何(custGeom)";
|
||||
}
|
||||
return "未指定几何";
|
||||
}
|
||||
|
||||
// 大小 - 高度
|
||||
public static String getShapeSizeHeight(Pic sp, CTSlideTiming timing) {
|
||||
CTTransform2D xfrm = sp.getSpPr().getXfrm();
|
||||
@@ -258,6 +289,7 @@ public class ShapePic {
|
||||
// 3) 未设置 → 视为实线
|
||||
return "solid";
|
||||
}
|
||||
|
||||
// 形状线条 开始箭头类型
|
||||
public static String getShapeLineStartArrow(Pic sp, CTSlideTiming timing) {
|
||||
CTShapeProperties spPr = sp.getSpPr();
|
||||
@@ -269,14 +301,17 @@ public class ShapePic {
|
||||
}
|
||||
return "无箭头";
|
||||
}
|
||||
|
||||
// 形状线条 开始箭头粗细
|
||||
public static String getShapeLineStartArrowWidth(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 形状线条 结尾箭头类型
|
||||
public static String getShapeLineEndArrow(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 形状线条 结尾箭头粗细
|
||||
public static String getShapeLineEndArrowWidth(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
@@ -349,12 +384,12 @@ public class ShapePic {
|
||||
} else if (coverage >= 0.45) {
|
||||
coverageLabel = "半倒影";
|
||||
} else {
|
||||
coverageLabel = "短倒影";
|
||||
coverageLabel = "紧密倒影";
|
||||
}
|
||||
|
||||
// —— 2) 偏移描述:dist EMU -> pt;<1pt 视作“紧贴”,否则 "Xpt 偏移" —— //
|
||||
// —— 2) 偏移描述:dist EMU -> pt;<1pt 视作“接触”,否则 "Xpt 偏移" —— //
|
||||
double distPt = emuToPt(r.getDist()); // 可能为 0
|
||||
String offsetLabel = distPt < 1.0 ? "紧贴" : (SlideUtils.fmt1(distPt) + "pt 偏移");
|
||||
String offsetLabel = distPt < 1.0 ? "接触" : (SlideUtils.fmt1(distPt) + "pt 偏移");
|
||||
|
||||
return coverageLabel + " " + offsetLabel;
|
||||
}
|
||||
@@ -383,14 +418,17 @@ public class ShapePic {
|
||||
CTSoftEdgesEffect se = getSoftEdge(sp);
|
||||
return (se != null) ? String.valueOf(se.getRad()) : null;
|
||||
}
|
||||
|
||||
// 形状效果 三维效果→绘制
|
||||
public static String getShape3DEffectDraw(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 形状效果 三维格式→效果
|
||||
public static String getShape3DEffect(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
}
|
||||
|
||||
// 形状效果 三维旋转→效果
|
||||
public static String getShape3DRotation(Pic sp, CTSlideTiming timing) {
|
||||
return "待开发";
|
||||
@@ -425,6 +463,7 @@ public class ShapePic {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getAniationInfo(List<Object> objects, List<Object> upObjects, String spId, String parameter) {
|
||||
boolean isDur = false;
|
||||
boolean isDirection = false;
|
||||
@@ -438,7 +477,33 @@ public class ShapePic {
|
||||
// 判断方向
|
||||
if (isDirection) {
|
||||
if (object instanceof CTTLAnimateEffectBehavior) {
|
||||
return ((CTTLAnimateEffectBehavior) object).getFilter();
|
||||
return Transition.effectWithDirToChinese(((CTTLAnimateEffectBehavior) object).getFilter());
|
||||
} else {
|
||||
// 获取行动轨迹
|
||||
for (Object ob : objects) {
|
||||
if (ob instanceof CTTLAnimateBehavior) {
|
||||
List<CTTLTimeAnimateValue> cttlTimeAnimateValues = ((CTTLAnimateBehavior) ob).getTavLst().getTav();
|
||||
for (CTTLTimeAnimateValue cttlTimeAnimateValue : cttlTimeAnimateValues) {
|
||||
if (cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("0-#ppt_h/") ||
|
||||
cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("-#ppt_h")) {
|
||||
return "自顶部";
|
||||
}
|
||||
if (cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("#ppt_h+") ||
|
||||
cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("+#ppt_h")) {
|
||||
return "自底部";
|
||||
}
|
||||
if (cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("+#ppt_w") ||
|
||||
cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("#ppt_w+")) {
|
||||
return "自右侧";
|
||||
}
|
||||
if (cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("0-#ppt_w/") ||
|
||||
cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("-#ppt_w") ||
|
||||
cttlTimeAnimateValue.getVal().getStrVal().getVal().contains("-N")) {
|
||||
return "自左侧";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (object instanceof CTTLSetBehavior) {
|
||||
|
@@ -1,12 +1,10 @@
|
||||
package pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j;
|
||||
|
||||
import org.apache.poi.xslf.usermodel.XMLSlideShow;
|
||||
import org.apache.poi.xslf.usermodel.XSLFSlide;
|
||||
import org.apache.xmlbeans.XmlCursor;
|
||||
import org.docx4j.openpackaging.packages.OpcPackage;
|
||||
import org.docx4j.openpackaging.packages.PresentationMLPackage;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.NotesMasterPart;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.SlideMasterPart;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.SlidePart;
|
||||
import org.pptx4j.pml.CTSlideTiming;
|
||||
import org.pptx4j.pml.GroupShape;
|
||||
import org.pptx4j.pml.Pic;
|
||||
import org.pptx4j.pml.Shape;
|
||||
@@ -35,25 +33,27 @@ public class SlideConversion {
|
||||
String firstId = getStringRandom();
|
||||
setSlideDataInfo(firstId, "", "幻灯片", "slide", "", false, "", dataInfoVOS);
|
||||
for (SlidePart slidePart : slideParts) {
|
||||
slideIndexFoFile ++;
|
||||
// 第三层
|
||||
String secondId = getStringRandom();
|
||||
setSlideDataInfo(secondId, firstId, "第"+slideIndexFoFile+"页", "sld", String.valueOf(slideIndexFoFile), false, "", dataInfoVOS);
|
||||
String thirdSettingId = getStringRandom();
|
||||
String thirdId = getStringRandom();
|
||||
slideIndexFoFile++;
|
||||
setSlideDataInfo(secondId, firstId, "第" + slideIndexFoFile + "页", "sld", String.valueOf(slideIndexFoFile), false, "", dataInfoVOS);
|
||||
setSlideDataInfo(thirdSettingId, secondId, "幻灯片设置", "slideSetting", String.valueOf(slideIndexFoFile) + "_0", true, "第" + slideIndexFoFile + "页", dataInfoVOS);
|
||||
setSlideDataInfo(thirdId, secondId, "形状", "shapeMaster", "", false, "", dataInfoVOS);
|
||||
// 获取形状
|
||||
GroupShape spTree = slidePart.getJaxbElement().getCSld().getSpTree();
|
||||
List<Object> shapes = spTree.getSpOrGrpSpOrGraphicFrame();
|
||||
int slideIndexFoShape = 0;
|
||||
// 第三层
|
||||
String thirdId = getStringRandom();
|
||||
setSlideDataInfo(thirdId, secondId, "幻灯片设置", "slideSetting", String.valueOf(slideIndexFoFile) + "_0", true, "第"+slideIndexFoFile+"页", dataInfoVOS);
|
||||
for (Object shapeObj : shapes) {
|
||||
slideIndexFoShape ++;
|
||||
slideIndexFoShape++;
|
||||
// 形状
|
||||
String fourId = getStringRandom();
|
||||
if (shapeObj instanceof Shape) {
|
||||
setSlideDataInfo(fourId, secondId, "形状"+slideIndexFoShape+"->"+((Shape) shapeObj).getNvSpPr().getCNvPr().getName(), "shape", String.valueOf(slideIndexFoFile) + "_" + String.valueOf(slideIndexFoShape), true, "第"+slideIndexFoFile+"页", dataInfoVOS);
|
||||
setSlideDataInfo(fourId, thirdId, "形状" + slideIndexFoShape + "->" + ((Shape) shapeObj).getNvSpPr().getCNvPr().getName(), "shape", String.valueOf(slideIndexFoFile) + "_" + String.valueOf(slideIndexFoShape), true, "第" + slideIndexFoFile + "页", dataInfoVOS);
|
||||
}
|
||||
if (shapeObj instanceof Pic) {
|
||||
setSlideDataInfo(fourId, secondId, "形状"+slideIndexFoShape+"->"+((Pic) shapeObj).getNvPicPr().getCNvPr().getName(), "shape", String.valueOf(slideIndexFoFile) + "_" + String.valueOf(slideIndexFoShape), true, "第"+slideIndexFoFile+"页", dataInfoVOS);
|
||||
setSlideDataInfo(fourId, thirdId, "形状" + slideIndexFoShape + "->" + ((Pic) shapeObj).getNvPicPr().getCNvPr().getName(), "shape", String.valueOf(slideIndexFoFile) + "_" + String.valueOf(slideIndexFoShape), true, "第" + slideIndexFoFile + "页", dataInfoVOS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,61 @@ public class SlideConversion {
|
||||
String secondSetId = getStringRandom();
|
||||
setSlideDataInfo(firstSetId, "", "设置", "slideAllSetting", "", false, "", dataInfoVOS);
|
||||
setSlideDataInfo(secondSetId, firstSetId, "幻灯片设置", "slideAllSetting", "0_0", true, "设置", dataInfoVOS);
|
||||
|
||||
// 幻灯片母版
|
||||
String firstModelId = getStringRandom();
|
||||
String secondModelId = getStringRandom();
|
||||
SlideMasterPart slideMasterPart = SlideMasterUtils.getSlideMaster(ppt);
|
||||
setSlideDataInfo(firstModelId, "", "母版", "slideModel", "", false, "", dataInfoVOS);
|
||||
// 获取母版的形状
|
||||
if (slideMasterPart != null) {
|
||||
setSlideDataInfo(secondModelId, firstModelId, "幻灯片母版", "shapeMaster", "", false, "", dataInfoVOS);
|
||||
List<Object> masterShapeList = slideMasterPart.getJaxbElement().getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame();
|
||||
int slideIndexForModel = 0;
|
||||
String thirdModelId = getStringRandom();
|
||||
String thirdModelSettingId = getStringRandom();
|
||||
for (Object shapeObj : masterShapeList) {
|
||||
String fourModelId = getStringRandom();
|
||||
if (slideIndexForModel == 0) {
|
||||
setSlideDataInfo(thirdModelSettingId, secondModelId, "幻灯片设置", "shapeMaster", "", true, "", dataInfoVOS);
|
||||
setSlideDataInfo(thirdModelId, secondModelId, "形状", "shapeMaster", "", false, "", dataInfoVOS);
|
||||
}
|
||||
slideIndexForModel++;
|
||||
if (shapeObj instanceof Shape) {
|
||||
String valueName = ((Shape) shapeObj).getNvSpPr().getCNvPr().getName();
|
||||
setSlideDataInfo(fourModelId, thirdModelId, "形状" + slideIndexForModel + "->" + valueName, "slideModel", "0_" + String.valueOf(slideIndexForModel), true, "第" + slideIndexForModel + "页", dataInfoVOS);
|
||||
}
|
||||
if (shapeObj instanceof Pic) {
|
||||
String valueName = ((Pic) shapeObj).getNvPicPr().getCNvPr().getName();
|
||||
setSlideDataInfo(fourModelId, thirdModelId, "形状" + slideIndexForModel + "->" + valueName, "slideModel", "0_" + String.valueOf(slideIndexForModel), true, "第" + slideIndexForModel + "页", dataInfoVOS);
|
||||
}
|
||||
}
|
||||
}
|
||||
String secondModelNodeId = getStringRandom();
|
||||
// 备注母版
|
||||
NotesMasterPart notesMasterPart = SlideMasterUtils.getNotesMaster(ppt);
|
||||
if (notesMasterPart != null) {
|
||||
setSlideDataInfo(secondModelNodeId, firstModelId, "备注母版", "shapeNotesMaster", "", false, "", dataInfoVOS);
|
||||
List<Object> masterShapeList = notesMasterPart.getJaxbElement().getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame();
|
||||
int slideIndexForModel = 0;
|
||||
String thirdModelId = getStringRandom();
|
||||
String thirdModelSettingId = getStringRandom();
|
||||
for (Object shapeObj : masterShapeList) {
|
||||
String fourModelId = getStringRandom();
|
||||
if (slideIndexForModel == 0) {
|
||||
setSlideDataInfo(thirdModelSettingId, secondModelNodeId, "幻灯片设置", "shapeNotesMaster", "", true, "", dataInfoVOS);
|
||||
setSlideDataInfo(thirdModelId, secondModelNodeId, "形状", "shapeNotesMaster", "", false, "", dataInfoVOS);
|
||||
}
|
||||
slideIndexForModel++;
|
||||
if (shapeObj instanceof Shape) {
|
||||
String valueName = ((Shape) shapeObj).getNvSpPr().getCNvPr().getName();
|
||||
setSlideDataInfo(fourModelId, thirdModelId, "形状" + slideIndexForModel + "->" + valueName, "shapeNotesMaster", "0_" + String.valueOf(slideIndexForModel), true, "第" + slideIndexForModel + "页", dataInfoVOS);
|
||||
}
|
||||
if (shapeObj instanceof Pic) {
|
||||
String valueName = ((Pic) shapeObj).getNvPicPr().getCNvPr().getName();
|
||||
setSlideDataInfo(fourModelId, thirdModelId, "形状" + slideIndexForModel + "->" + valueName, "shapeNotesMaster", "0_" + String.valueOf(slideIndexForModel), true, "第" + slideIndexForModel + "页", dataInfoVOS);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -85,7 +139,7 @@ public class SlideConversion {
|
||||
|
||||
// 想数组中添加数据
|
||||
public static void setSlideDataInfo(String id, String parentId, String text,
|
||||
String type, String index, boolean isTrue, String belongToName, List<SlideDataInfoVO> dataInfoVOS) throws Exception {
|
||||
String type, String index, boolean isTrue, String belongToName, List<SlideDataInfoVO> dataInfoVOS) throws Exception {
|
||||
SlideDataInfoVO dataInfo = new SlideDataInfoVO();
|
||||
dataInfo.setId(id);
|
||||
dataInfo.setParentId(parentId);
|
||||
|
@@ -6,13 +6,12 @@ import org.docx4j.openpackaging.packages.PresentationMLPackage;
|
||||
import org.docx4j.openpackaging.parts.JaxbXmlPart;
|
||||
import org.docx4j.openpackaging.parts.Part;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.MainPresentationPart;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.NotesMasterPart;
|
||||
import org.docx4j.openpackaging.parts.PresentationML.SlideMasterPart;
|
||||
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
|
||||
import org.docx4j.relationships.Relationship;
|
||||
import org.pptx4j.jaxb.Context;
|
||||
import org.pptx4j.pml.CTBackground;
|
||||
import org.pptx4j.pml.Presentation;
|
||||
import org.pptx4j.pml.PresentationPr;
|
||||
import org.pptx4j.pml.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -58,6 +57,42 @@ public class SlideMasterUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取备注母版 NotesMasterPart(若文件未显式定义备注母版则返回 null)
|
||||
*/
|
||||
public static NotesMasterPart getNotesMaster(PresentationMLPackage ppt) {
|
||||
// 2. 获取 Presentation 对象
|
||||
MainPresentationPart mpp = ppt.getMainPresentationPart();
|
||||
Presentation pres = (Presentation) mpp.getJaxbElement();
|
||||
RelationshipsPart rels = ppt.getMainPresentationPart().getRelationshipsPart();
|
||||
// 获取母版ID
|
||||
CTNotesMasterIdList idList = pres.getNotesMasterIdLst();
|
||||
CTNotesMasterIdListEntry smId = idList.getNotesMasterId();
|
||||
String rId = null;
|
||||
try {
|
||||
rId = smId.getId(); // 新一点的模型常见
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
if (rId == null) {
|
||||
try {
|
||||
// 某些版本字段名为 id2(即 r:id)
|
||||
rId = (String) CTNotesMasterIdList.class.getMethod("getId2").invoke(smId);
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
}
|
||||
Relationship rel = rels.getRelationshipByID(rId);
|
||||
// 再通过关系拿到具体的 Part
|
||||
Part part = rels.getPart(rel);
|
||||
if (part instanceof NotesMasterPart) {
|
||||
NotesMasterPart notes = (NotesMasterPart) part;
|
||||
return notes;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// /ppt/presProps.xml 的关系类型
|
||||
private static final String REL_TYPE_PRES_PROPS =
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps";
|
||||
|
@@ -0,0 +1,116 @@
|
||||
package pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j.utils;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class HexColorUtils {
|
||||
|
||||
// 常见颜色映射表(可按需扩展)
|
||||
private static final Map<String, String> COLOR_NAME_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
// -------------------- 基础色 --------------------
|
||||
COLOR_NAME_MAP.put("#000000", "黑色");
|
||||
COLOR_NAME_MAP.put("#FFFFFF", "白色");
|
||||
COLOR_NAME_MAP.put("#FF0000", "红色");
|
||||
COLOR_NAME_MAP.put("#00FF00", "亮绿色");
|
||||
COLOR_NAME_MAP.put("#0000FF", "蓝色");
|
||||
COLOR_NAME_MAP.put("#FFFF00", "黄色");
|
||||
COLOR_NAME_MAP.put("#00FFFF", "青色");
|
||||
COLOR_NAME_MAP.put("#FF00FF", "洋红色");
|
||||
|
||||
// -------------------- Office 常见标准色 --------------------
|
||||
COLOR_NAME_MAP.put("#0070C0", "蓝色");
|
||||
COLOR_NAME_MAP.put("#00B050", "绿色");
|
||||
COLOR_NAME_MAP.put("#7030A0", "紫罗兰色");
|
||||
COLOR_NAME_MAP.put("#C00000", "深红色");
|
||||
COLOR_NAME_MAP.put("#FFC000", "橙黄色");
|
||||
|
||||
// -------------------- 灰阶 --------------------
|
||||
COLOR_NAME_MAP.put("#808080", "灰色");
|
||||
COLOR_NAME_MAP.put("#C0C0C0", "银色");
|
||||
COLOR_NAME_MAP.put("#A9A9A9", "深灰色");
|
||||
COLOR_NAME_MAP.put("#D3D3D3", "浅灰色");
|
||||
COLOR_NAME_MAP.put("#F5F5F5", "白烟色");
|
||||
|
||||
// -------------------- 常见网页颜色 --------------------
|
||||
COLOR_NAME_MAP.put("#800000", "栗色");
|
||||
COLOR_NAME_MAP.put("#808000", "橄榄色");
|
||||
COLOR_NAME_MAP.put("#800080", "紫色");
|
||||
COLOR_NAME_MAP.put("#008080", "水鸭色");
|
||||
COLOR_NAME_MAP.put("#FFA500", "橙色");
|
||||
COLOR_NAME_MAP.put("#A52A2A", "棕色");
|
||||
COLOR_NAME_MAP.put("#F5F5DC", "米色");
|
||||
COLOR_NAME_MAP.put("#FFC0CB", "粉红色");
|
||||
COLOR_NAME_MAP.put("#ADD8E6", "浅蓝色");
|
||||
COLOR_NAME_MAP.put("#90EE90", "浅绿色");
|
||||
COLOR_NAME_MAP.put("#FFD700", "金色");
|
||||
COLOR_NAME_MAP.put("#FA8072", "鲑鱼色");
|
||||
COLOR_NAME_MAP.put("#FF4500", "橙红色");
|
||||
COLOR_NAME_MAP.put("#4682B4", "钢蓝色");
|
||||
COLOR_NAME_MAP.put("#2E8B57", "海绿色");
|
||||
COLOR_NAME_MAP.put("#B22222", "耐火砖红");
|
||||
COLOR_NAME_MAP.put("#6B8E23", "橄榄褐色");
|
||||
COLOR_NAME_MAP.put("#DAA520", "秋麒麟色");
|
||||
COLOR_NAME_MAP.put("#5F9EA0", "军服蓝");
|
||||
COLOR_NAME_MAP.put("#D2691E", "巧克力色");
|
||||
|
||||
// -------------------- WPS/Excel 扩展色 --------------------
|
||||
COLOR_NAME_MAP.put("#1F497D", "深蓝色");
|
||||
COLOR_NAME_MAP.put("#4F81BD", "中蓝色");
|
||||
COLOR_NAME_MAP.put("#9BBB59", "草绿色");
|
||||
COLOR_NAME_MAP.put("#8064A2", "紫罗兰色");
|
||||
COLOR_NAME_MAP.put("#F79646", "杏橙色");
|
||||
COLOR_NAME_MAP.put("#C0504D", "砖红色");
|
||||
|
||||
COLOR_NAME_MAP.put("#31869B", "蓝绿色");
|
||||
COLOR_NAME_MAP.put("#E46C0A", "深橙色");
|
||||
COLOR_NAME_MAP.put("#77933C", "苔藓绿");
|
||||
COLOR_NAME_MAP.put("#963634", "褐红色");
|
||||
COLOR_NAME_MAP.put("#4BACC6", "湖蓝色");
|
||||
COLOR_NAME_MAP.put("#604A7B", "深紫色");
|
||||
|
||||
// -------------------- 柔和色调 --------------------
|
||||
COLOR_NAME_MAP.put("#B6DDE8", "浅湖蓝色");
|
||||
COLOR_NAME_MAP.put("#E6B8B7", "浅褐红色");
|
||||
COLOR_NAME_MAP.put("#D8E4BC", "浅草绿色");
|
||||
COLOR_NAME_MAP.put("#CCC0DA", "浅紫色");
|
||||
COLOR_NAME_MAP.put("#F2DCDB", "浅玫瑰色");
|
||||
COLOR_NAME_MAP.put("#B8CCE4", "浅蓝灰色");
|
||||
}
|
||||
|
||||
/**
|
||||
* 把十六进制颜色转成 "颜色名 RGB(r,g,b)" 格式的字符串
|
||||
* @param hex 十六进制颜色,例如 "00B050" 或 "#00B050"
|
||||
* @return 格式化后的字符串
|
||||
*/
|
||||
public static String hexToColorString(String hex) {
|
||||
if (hex == null || hex.isEmpty()) {
|
||||
return "无效颜色";
|
||||
}
|
||||
|
||||
// 去掉 # 前缀
|
||||
if (hex.startsWith("#")) {
|
||||
hex = hex.substring(1);
|
||||
}
|
||||
|
||||
// 转换为 Color
|
||||
Color color = new Color(Integer.parseInt(hex, 16));
|
||||
int r = color.getRed();
|
||||
int g = color.getGreen();
|
||||
int b = color.getBlue();
|
||||
|
||||
// 转回统一的十六进制形式(大写,带 #)
|
||||
String hexKey = String.format("#%02X%02X%02X", r, g, b);
|
||||
|
||||
// 查找颜色名
|
||||
String name = COLOR_NAME_MAP.getOrDefault(hexKey, "未知颜色");
|
||||
|
||||
return String.format("%s RGB(%d,%d,%d)", name, r, g, b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -24,19 +24,4 @@ public class PtToCmConverter {
|
||||
public static double cmToPoints(double cm) {
|
||||
return cm / PT_TO_CM;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 示例转换
|
||||
double points = 10.0;
|
||||
double cm = pointsToCm(points);
|
||||
|
||||
System.out.println(points + " pt = " + cm + " cm");
|
||||
System.out.println("反向转换: " + cm + " cm = " + cmToPoints(cm) + " pt");
|
||||
|
||||
// 常见值的转换示例
|
||||
System.out.println("\n常见值转换:");
|
||||
System.out.println("8 pt = " + pointsToCm(8) + " cm");
|
||||
System.out.println("12 pt = " + pointsToCm(12) + " cm");
|
||||
System.out.println("72 pt = " + pointsToCm(72) + " cm (1 inch)");
|
||||
}
|
||||
}
|
@@ -1,6 +1,13 @@
|
||||
package pc.exam.pp.module.judgement.utils.wps_pptx.pptx4j.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.*;
|
||||
|
||||
public class Transition {
|
||||
|
||||
private static final Pattern P = Pattern.compile("\\(([^)]+)\\)");
|
||||
public static String getCnName(String fileName) {
|
||||
if (fileName == null) return "未知";
|
||||
|
||||
@@ -121,4 +128,79 @@ public class Transition {
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDirection(String spec) {
|
||||
if (spec == null) return null;
|
||||
Matcher m = P.matcher(spec);
|
||||
return m.find() ? m.group(1).trim() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将方向英文/短码汉化;可直接传入诸如 "downRight"、"rd"、"rightDown"、"vert"、"in" 等。
|
||||
* @param raw 方向原始字符串(不区分大小写,允许下划线/中横线/驼峰)
|
||||
* @return 对应的中文(若无法识别,原样返回)
|
||||
*/
|
||||
public static String toChinese(String raw) {
|
||||
if (raw == null || raw.isEmpty()) return raw;
|
||||
String s = normalize(raw);
|
||||
|
||||
switch (s) {
|
||||
// 单向
|
||||
case "l": case "left": return "向左";
|
||||
case "r": case "right": return "向右";
|
||||
case "u": case "up": return "向上";
|
||||
case "d": case "down": return "向下";
|
||||
|
||||
// 斜向
|
||||
case "lu": case "upleft": case "leftup": return "左上";
|
||||
case "ru": case "upright": case "rightup": return "右上";
|
||||
case "ld": case "downleft": case "leftdown": return "左下";
|
||||
case "rd": case "downright": case "rightdown": return "右下";
|
||||
|
||||
// 其他常见关键字
|
||||
case "vert": case "vertical": return "垂直";
|
||||
case "horz": case "horizontal": return "水平";
|
||||
case "in": return "向内";
|
||||
case "out": return "向外";
|
||||
|
||||
default:
|
||||
return raw; // 不识别则原样返回,避免误判
|
||||
}
|
||||
}
|
||||
|
||||
/** 归一化:去空格/分隔符、转小写、转驼峰组合为连续词 */
|
||||
private static String normalize(String s) {
|
||||
s = s.trim().toLowerCase(Locale.ROOT);
|
||||
s = s.replaceAll("[_\\-\\s]", ""); // 去掉下划线/中横线/空格
|
||||
return s;
|
||||
}
|
||||
|
||||
/** 示例:把效果+方向组合成人类可读中文,比如 "strips(downRight)" → "条纹(右下)" */
|
||||
public static String effectWithDirToChinese(String dir) {
|
||||
return toChinese(getDirection(dir));
|
||||
}
|
||||
|
||||
/** 常见效果英文→中文(可按需扩展) */
|
||||
public static String effectToChinese(String effect) {
|
||||
if (effect == null) return "效果";
|
||||
String e = effect.trim().toLowerCase(Locale.ROOT);
|
||||
switch (e) {
|
||||
case "strips": return "条纹";
|
||||
case "blinds": return "百叶窗";
|
||||
case "wipe": return "擦除";
|
||||
case "push": return "推出";
|
||||
case "split": return "分割";
|
||||
case "checkerboard":return "棋盘格";
|
||||
case "cover": return "覆盖";
|
||||
case "uncover": return "揭开";
|
||||
case "randombars": return "随机条";
|
||||
case "shape": return "形状";
|
||||
case "circle": return "圆形";
|
||||
case "diamond": return "菱形";
|
||||
case "plus": return "十字形";
|
||||
case "fade": return "淡入";
|
||||
case "appear": return "出现";
|
||||
default: return effect; // 未收录则原样
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user