Accept Merge Request #156: (hyc -> master)

Merge Request: 【修改】新增word考点

Created By: @华允传
Accepted By: @华允传
URL: https://g-iswv8783.coding.net/p/education/d/pengchen-exam-java/git/merge/156?initial=true
This commit is contained in:
华允传
2025-08-25 21:04:44 +08:00
committed by Coding
5 changed files with 616 additions and 290 deletions

View File

@@ -16,6 +16,8 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphical
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotTableDefinition;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.XMLConstants;
@@ -24,8 +26,10 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
@@ -329,22 +333,62 @@ public class ChartHandler {
/** 图表-设计 - 图表样式 */
public String getChartStyle(XSSFChart chart, XSSFSheet sheet) {
if (chart == null) return "无图表";
//
// CTChart ctChart = chart.getCTChart();
// if (ctChart == null) return "无样式";
//
// CTPlotArea plotArea = ctChart.getPlotArea();
// if (plotArea != null && plotArea.getExtLst() != null) {
// // 可以进一步解析 extLst 获取自定义样式信息
// }
//
// // 尝试直接从 plotArea 或 chart XML 属性里获取 style
// if (ctChart.getDomNode().getAttributes().getNamedItem("style") != null) {
// String style = ctChart.getDomNode().getAttributes().getNamedItem("style").getNodeValue();
// return "样式" + style;
// }
try {
Node chartNode = chart.getCTChartSpace().getDomNode();
return "默认样式";
// 先尝试取 c14:style
NodeList c14StyleNodes = ((Element) chartNode)
.getElementsByTagNameNS("http://schemas.microsoft.com/office/drawing/2007/8/2/chart", "style");
if (c14StyleNodes.getLength() > 0) {
String val = ((Element) c14StyleNodes.item(0)).getAttribute("val");
int styleId = Integer.parseInt(val);
// 映射 101114 → 114
if (styleId >= 101 && styleId <= 114) {
styleId -= 100;
}
return "样式" + styleId;
}
// 再尝试取 c:style
NodeList cStyleNodes = ((Element) chartNode)
.getElementsByTagNameNS("http://schemas.openxmlformats.org/drawingml/2006/chart", "style");
if (cStyleNodes.getLength() > 0) {
String val = ((Element) cStyleNodes.item(0)).getAttribute("val");
int styleId = Integer.parseInt(val);
return "样式" + styleId;
}
return "未定义样式";
} catch (Exception e) {
e.printStackTrace();
return "解析图表样式时出错: " + e.getMessage();
}
}
/**
* 打印图表对应的 XML
*/
public static void printChartXml(XSSFChart chart) {
if (chart == null) {
System.out.println("无图表");
return;
}
try {
PackagePart part = chart.getPackagePart();
try (InputStream is = part.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("读取图表XML失败: " + e.getMessage());
}
}
@@ -375,8 +419,18 @@ public class ChartHandler {
return "";
}
/**
* 获取所有可用图表样式名称列表
*/
public static String[] getAllChartStyles() {
String[] styles = new String[14];
for (int i = 0; i < 14; i++) {
styles[i] = "样式" + (i + 1);
}
return styles;
}
/** 获取图表宽度,返回"磅(厘米)" */
/** 获取图表宽度,返回"磅(厘米)" */
//todo
public static String getChartWidth(XSSFChart chart, XSSFSheet sheet) {
if (chart == null || sheet == null) return "";
@@ -520,23 +574,23 @@ public class ChartHandler {
}
public void printChartXml(XSSFChart chart) {
if (chart == null) {
System.out.println("无图表");
return;
}
try {
PackagePart part = chart.getPackagePart();
try (InputStream is = part.getInputStream()) {
String xml = new String(is.readAllBytes(), StandardCharsets.UTF_8);
System.out.println("===== chart.xml 内容 =====");
System.out.println(xml);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// public void printChartXml(XSSFChart chart) {
// if (chart == null) {
// System.out.println("无图表");
// return;
// }
//
// try {
// PackagePart part = chart.getPackagePart();
// try (InputStream is = part.getInputStream()) {
// String xml = new String(is.readAllBytes(), StandardCharsets.UTF_8);
// System.out.println("===== chart.xml 内容 =====");
// System.out.println(xml);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// }

View File

@@ -67,7 +67,7 @@ public class TableIng {
Node attr = node.getAttributes().getNamedItem("name");
if (attr != null) {
// 适应不同格式
String val = attr.getNodeValue().toLowerCase();
String val = attr.getNodeValue().toLowerCase();
return val;
}
return "";

View File

@@ -232,7 +232,7 @@ public class Drawing {
if (pic == null) {
// 处理未找到图片的情况
return null;
return "";
}
// 继续处理 pic获取轮廓颜色
@@ -247,7 +247,7 @@ public class Drawing {
}
}
return null;
return "";
}
@@ -268,7 +268,7 @@ public class Drawing {
if (pic == null) {
// 处理找不到图片的情况
return null;
return "";
}
if (pic.getSpPr() != null && pic.getSpPr().getLn() != null) {
@@ -280,7 +280,7 @@ public class Drawing {
}
return null;
return "";
}
@@ -300,7 +300,7 @@ public class Drawing {
if (pic == null) {
// 找不到图片对象,返回 null
return null;
return "";
}
if (pic.getSpPr() != null && pic.getSpPr().getLn() != null) {
@@ -311,7 +311,7 @@ public class Drawing {
}
}
return null;
return "";
}
// 形状轮廓 虚线(短划线类型)
@@ -329,7 +329,7 @@ public class Drawing {
}
if (pic == null) {
return null;
return "";
}
if (pic.getSpPr() != null && pic.getSpPr().getLn() != null) {
@@ -339,7 +339,7 @@ public class Drawing {
}
}
return null;
return "";
}
@@ -369,14 +369,14 @@ public class Drawing {
if (!(value instanceof Pic)) {
System.out.println("value不是Pic类型实际类型" + value.getClass().getName());
return null;
return "";
}
Pic pic = (Pic) value;
if (pic.getSpPr() == null || pic.getSpPr().getLn() == null) {
System.out.println("ln为空无法获取轮廓透明度");
return null;
return "";
}
CTLineProperties ln = pic.getSpPr().getLn();
@@ -384,7 +384,7 @@ public class Drawing {
if (solidFill == null) {
System.out.println("solidFill为空");
return null;
return "";
}
// 优先处理 srgbClr
@@ -458,7 +458,7 @@ public class Drawing {
}
}
return null;
return "";
}
@@ -601,7 +601,7 @@ public class Drawing {
}
}
return "未知";
return "";
}
//模糊
@@ -768,7 +768,7 @@ public class Drawing {
} catch (Exception e) {
// ignore
}
return null;
return "";
}
private static Integer tryGetVal(Object alphaObj) {
@@ -893,23 +893,23 @@ public class Drawing {
CTShapeProperties spPr = getShapeProperties(anchor);
if (spPr == null) return null;
if (spPr == null) return "";
if (spPr.getSolidFill() != null) return "纯色填充";
if (spPr.getBlipFill() != null) return "图片填充";
if (spPr.getPattFill() != null) return "图案填充";
return null;
return "";
}
// marshalShapeProperties(spPr);
public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS, Anchor anchor, int betoLong, WordprocessingMLPackage wordMLPackage) {
CTShapeProperties spPr = getShapeProperties(anchor);
if (spPr == null) {
return null;
return "";
}
CTSolidColorFillProperties solidFill = spPr.getSolidFill();
if (solidFill == null) {
return null;
return "";
}
if (solidFill.getSrgbClr() != null) {
@@ -924,16 +924,16 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
}
System.out.println("全部颜色属性均为空!");
return null;
return "";
}
// 纯色填充→透明度
public static String getPictureFillTransparency(List<JudgementWordsVO> judgementWordsVOS, Anchor anchor, int betoLong, WordprocessingMLPackage wordMLPackage) {
CTShapeProperties spPr = getShapeProperties(anchor);
if (spPr == null) return null;
if (spPr == null) return "";
CTSolidColorFillProperties solidFill = spPr.getSolidFill();
if (solidFill == null) return null;
if (solidFill == null) return "";
// 检查 srgbClr
if (solidFill.getSrgbClr() != null) {
@@ -1012,18 +1012,18 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
}
if (!(value instanceof Pic)) {
return "纹理填充透明度";
return "";
}
Pic pic = (Pic) value;
if (pic.getSpPr() == null || pic.getSpPr().getBlipFill() == null) {
return "纹理填充透明度";
return "";
}
Object blipObj = pic.getSpPr().getBlipFill().getBlip();
if (blipObj == null) {
return "纹理填充透明度";
return "";
}
// 调用 getAlphaBiLevelOrAlphaCeilingOrAlphaFloor 方法
@@ -1069,7 +1069,7 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
return "读取异常";
}
return "纹理填充透明度";
return "";
}
private static String getAlphaModFixTransparencyFromBlipFill(Object blipFill) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
@@ -1182,38 +1182,38 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
//图案填充→图案
public static String getPatternFillPattern(List<JudgementWordsVO> judgementWordsVOS, Anchor anchor, int betoLong, WordprocessingMLPackage wordMLPackage) {
CTPatternFillProperties pattFill = getShapeProperties(anchor) == null ? null : getShapeProperties(anchor).getPattFill();
if (pattFill == null) return "图案填充";
if (pattFill == null) return "";
// 这里直接返回枚举toString或value()也可以直接用toString()
Object prst = pattFill.getPrst();
if (prst != null) {
return prst.toString();
}
return "未知图案";
return "";
}
//图案填充→前景色
public static String getPatternFillForeColor(List<JudgementWordsVO> judgementWordsVOS, Anchor anchor, int betoLong, WordprocessingMLPackage wordMLPackage) {
CTPatternFillProperties pattFill = getShapeProperties(anchor) == null ? null : getShapeProperties(anchor).getPattFill();
if (pattFill == null) return "图案填充";
if (pattFill == null) return "";
if (pattFill.getFgClr() != null) {
System.out.println(extractColor(pattFill.getFgClr()));
return ColorUtils.getChineseColorName(extractColor(pattFill.getFgClr()));
}
return "前景色";
return "";
}
//图案填充→背景色
public static String getPatternFillBackColor(List<JudgementWordsVO> judgementWordsVOS, Anchor anchor, int betoLong, WordprocessingMLPackage wordMLPackage) {
CTPatternFillProperties pattFill = getShapeProperties(anchor) == null ? null : getShapeProperties(anchor).getPattFill();
if (pattFill == null) return "图案填充";
if (pattFill == null) return "";
if (pattFill.getBgClr() != null) {
System.out.println(extractColor(pattFill.getBgClr()));
return ColorUtils.getChineseColorName(extractColor(pattFill.getBgClr()));
}
return "背景色";
return "";
}
//形状效果(倒影)
@@ -1242,7 +1242,7 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
// 2. 预设类型shadow preset
public static String getShadowPreset(List<JudgementWordsVO> judgementWordsVOS, Anchor anchor, int betoLong, WordprocessingMLPackage wordMLPackage) {
CTReflectionEffect shadow = getReflectionEffect(anchor);
if (shadow == null) return "预设";
if (shadow == null) return "";
// 例如根据blurRad、dist、dir组合判断
BigInteger blurRad = BigInteger.valueOf(shadow.getBlurRad());
@@ -1265,17 +1265,17 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
|| anchor.getGraphic() == null
|| anchor.getGraphic().getGraphicData() == null
|| anchor.getGraphic().getGraphicData().getPic() == null) {
return "倒影";
return "";
}
CTShapeProperties spPr = anchor.getGraphic().getGraphicData().getPic().getSpPr();
if (spPr == null) return "倒影";
if (spPr == null) return "";
CTEffectList effectList = spPr.getEffectLst();
if (effectList == null) return "倒影";
if (effectList == null) return "";
CTReflectionEffect reflection = effectList.getReflection();
if (reflection == null) return "倒影";
if (reflection == null) return "";
// 读取起始透明度 stA 和结束透明度 endA类型是 Integer
Integer stA = reflection.getStA(); // 起始透明度
@@ -1312,11 +1312,11 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
marshaller.marshal(value, writer);
System.out.println(writer.toString());
CTReflectionEffect shadow = getReflectionEffect(anchor);
if (shadow == null) return "大小";
if (shadow == null) return "";
// 这里使用 sy 代表倒影大小比例,单位是 1/100000
Integer sy = shadow.getEndPos();
if (sy == null) return "大小";
if (sy == null) return "";
// 转换为百分比sy=100000表示100%
// 计算绝对值因为sy可能是负值表示倒影翻转
@@ -1329,10 +1329,10 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
// 5. 模糊半径(单位磅)
public static String getShadowBlurs(List<JudgementWordsVO> judgementWordsVOS, Anchor anchor, int betoLong, WordprocessingMLPackage wordMLPackage) {
CTReflectionEffect reflection = getReflectionEffect(anchor);
if (reflection == null) return "模糊";
if (reflection == null) return "";
Integer blurRad = Math.toIntExact(reflection.getBlurRad());
if (blurRad == null) return "模糊";
if (blurRad == null) return "";
// EMU转磅
double blurPt = blurRad * 72.0 / 914400.0;
@@ -1342,10 +1342,10 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
// 6. 距离(单位磅)
public static String getShadowDistances(List<JudgementWordsVO> judgementWordsVOS, Anchor anchor, int betoLong, WordprocessingMLPackage wordMLPackage) {
CTReflectionEffect reflection = getReflectionEffect(anchor);
if (reflection == null) return "距离";
if (reflection == null) return "";
Integer dist = Math.toIntExact(reflection.getDist());
if (dist == null) return "距离";
if (dist == null) return "";
// EMU转磅
double distPt = dist * 72.0 / 914400.0;
@@ -1375,7 +1375,7 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
// 图片-形状效果→柔化边缘→大小(磅)
public static String getSoftEdgeSize(List<JudgementWordsVO> judgementWordsVOS, Anchor anchor, int betoLong, WordprocessingMLPackage wordMLPackage) {
if (anchor == null || anchor.getGraphic() == null || anchor.getGraphic().getGraphicData() == null)
return "柔化";
return "";
Object anyObj = anchor.getGraphic().getGraphicData().getAny().get(0);
Object obj = (anyObj instanceof JAXBElement) ? ((JAXBElement<?>) anyObj).getValue() : anyObj;
@@ -1393,24 +1393,7 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
} catch (Exception e) {
e.printStackTrace();
}
return "柔化";
}
// ----- 辅助方法 -----
private static BigInteger getReflectionSize(CTReflectionEffect reflection) {
if (reflection == null) return null;
try {
Method m = reflection.getClass().getMethod("getSz");
Object val = m.invoke(reflection);
if (val instanceof BigInteger) {
return (BigInteger) val;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
return "";
}
// 获取倒影对象
@@ -1433,59 +1416,6 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
return reflection;
}
// 从shadow中获取透明度alpha返回整数(0~100000)
private static Integer getAlphaVal(CTReflectionEffect reflection) {
if (reflection == null) return null;
try {
// 先尝试用反射取所有get开头的方法找透明度相关的
for (Method method : reflection.getClass().getMethods()) {
String name = method.getName();
if (name.startsWith("get") &&
(name.toLowerCase().contains("alpha") || name.toLowerCase().contains("amt"))) {
Object val = method.invoke(reflection);
if (val != null) {
// 如果是BigInteger或Integer返回
if (val instanceof BigInteger) {
return ((BigInteger) val).intValue();
} else if (val instanceof Integer) {
return (Integer) val;
} else if (val.getClass().getName().contains("CTPositiveFixedAngle") ||
val.getClass().getName().contains("CTAlpha")) {
// 进一步递归找val属性
Method getValMethod = val.getClass().getMethod("getVal");
Object v = getValMethod.invoke(val);
if (v instanceof BigInteger) return ((BigInteger) v).intValue();
if (v instanceof Integer) return (Integer) v;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
// 找不到就返回null
return null;
}
public static CTShapeProperties getShapeProperties(Anchor anchor) {
if (anchor == null
|| anchor.getGraphic() == null
@@ -1523,13 +1453,6 @@ public static String getSolidFillColor(List<JudgementWordsVO> judgementWordsVOS,
return null;
}
public static String extractColor(CTColor ctColor) {
if (ctColor == null) return "无色";

View File

@@ -583,17 +583,35 @@ public class Paragraphs {
return "";
}
// 段落底纹 - 填充颜色
public static String getParagraphShdFillColor(P paragraph, StyleDefinitionsPart stylePart, WordprocessingMLPackage wordMLPackage, NumberingDefinitionsPart ndp) {
// 段落底纹 - 填充颜色(转为 rgb(r,g,b)
public static String getParagraphShdFillColor(P paragraph,
StyleDefinitionsPart stylePart,
WordprocessingMLPackage wordMLPackage,
NumberingDefinitionsPart ndp) {
// 先查询自身段落数据
PPr pPr = paragraph.getPPr();
if (pPr != null && pPr.getShd() != null) {
CTShd shd = pPr.getShd();
return shd.getFill();
String hex = shd.getFill(); // 例如 "FF0000"
if (hex != null && !hex.equals("auto") && !hex.equals("none")) {
try {
// 有些颜色可能写成三位或八位,先规范化
if (hex.length() == 6) {
int r = Integer.valueOf(hex.substring(0, 2), 16);
int g = Integer.valueOf(hex.substring(2, 4), 16);
int b = Integer.valueOf(hex.substring(4, 6), 16);
return String.format("RGB(%d,%d,%d)", r, g, b);
}
} catch (Exception e) {
return "";
}
}
}
return "";
}
// 段落底纹 - 图案样式
public static String getParagraphShdStyle(P paragraph, StyleDefinitionsPart stylePart, WordprocessingMLPackage wordMLPackage, NumberingDefinitionsPart ndp) {
// 先查询自身段落数据

View File

@@ -6,24 +6,24 @@ import org.docx4j.dml.Graphic;
import org.docx4j.dml.GraphicData;
import org.docx4j.dml.wordprocessingDrawing.Anchor;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.mce.AlternateContent;
import org.docx4j.model.structure.DocumentModel;
import org.docx4j.model.structure.HeaderFooterPolicy;
import org.docx4j.model.structure.SectionWrapper;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.WordprocessingML.*;
import org.docx4j.wml.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
import org.docx4j.wml.CTBorder;
import org.docx4j.wml.CTColumns;
import org.docx4j.wml.CTDocGrid;
import org.docx4j.wml.STPageOrientation;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import javax.xml.namespace.QName;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -165,6 +165,149 @@ public class SectionPage {
return linesPerPage + "行/页";
}
// 节 每页栏数
public static String getSectionPageLanNumber(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
if (paragraph == null || paragraph.getPPr() == null) return null;
SectPr sectPr = paragraph.getPPr().getSectPr();
if (sectPr == null) return null;
// 获取栏信息
CTColumns cols = sectPr.getCols();
if (cols == null) return "1栏/页"; // 默认单栏
// 获取栏数
BigInteger num = cols.getNum();
int colNum = (num != null ? num.intValue() : 1);
return colNum + "栏/页";
}
// 获取节的字体方向分为水平垂直中文旋转270°
public static String getSectionTextDirection(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
if (paragraph == null || paragraph.getPPr() == null) return "未知";
SectPr sectPr = paragraph.getPPr().getSectPr();
if (sectPr == null) return "";
// 获取文字方向
TextDirection textDir = sectPr.getTextDirection();
if (textDir == null || textDir.getVal() == null) {
return "水平"; // 默认水平方向
}
String val = String.valueOf(textDir.getVal());
switch (val) {
case "lrTb":
return "水平";
case "tbRl":
return "垂直";
case "lrTbV":
return "中文旋转270°";
default:
return "未知(" + val + ")";
}
}
// 每行字符数
// 每行字符数 + 每页行数
// public static String getSectionPageCharNumber(P paragraph,
// HeaderFooterPolicy hfp,
// WordprocessingMLPackage wordMLPackage,
// List<SectionWrapper> sections) {
// try {
// if (sections == null || sections.isEmpty()) {
// return "【没有节信息】";
// }
//
// // 这里只取第一个节(通常文档只有一个节,如果有多个可以 for 循环)
// SectionWrapper sectionWrapper = sections.get(0);
// SectPr sectPr = sectionWrapper.getSectPr();
// if (sectPr == null) {
// return "【无 SectPr 信息】";
// }
// System.out.println("==============");
//
//
//
// // 页面属性
// SectPr.PgSz pgSz = sectPr.getPgSz();
// SectPr.PgMar pgMar = sectPr.getPgMar();
// if (pgSz == null || pgMar == null) {
// return "【无页面设置】";
// }
//
// int pageW = pgSz.getW().intValue(); // 页面宽度 (twip)
// int pageH = pgSz.getH().intValue(); // 页面高度 (twip)
// int left = pgMar.getLeft().intValue();
// int right = pgMar.getRight().intValue();
// int top = pgMar.getTop().intValue();
// int bottom = pgMar.getBottom().intValue();
//
// // 可用区域
// int availableWidth = pageW - left - right;
// int availableHeight = pageH - top - bottom;
//
// // 网格设置
// CTDocGrid grid = sectPr.getDocGrid();
// if (grid == null) {
// return "【未设置文档网格】";
// }
//
// StringBuilder sb = new StringBuilder("【页面设置(文档网格)】");
//
// // 每行字符数
// if (grid.getCharSpace() != null) {
// int charSpace = grid.getCharSpace().intValue();
// if (charSpace > 0) {
// int charsPerLine = Math.round((float) availableWidth / charSpace);
// sb.append("【每行字符数】").append(charsPerLine).append(" 字/行");
// }
// }
//
// // 每页行数
// if (grid.getLinePitch() != null) {
// int linePitch = grid.getLinePitch().intValue();
// if (linePitch > 0) {
// int linesPerPage = Math.round((float) availableHeight / linePitch);
// sb.append("【每页行数】").append(linesPerPage).append(" 行/页");
// }
// }
//
// return sb.toString();
//
// } catch (Exception e) {
// return "【计算异常】" + e.getMessage();
// }
// }
/**
* 分栏情况下取单栏宽度
*/
private static int adjustForColumns(int totalWidthTwips, CTColumns cols) {
if (cols == null) return totalWidthTwips;
// 显式设置了 <w:col w="..."> 优先用第一栏
if (cols.getCol() != null && !cols.getCol().isEmpty()) {
CTColumn ctColumn = cols.getCol().get(0);
if (ctColumn.getW() != null && ctColumn.getW().intValue() > 0) {
return ctColumn.getW().intValue();
}
}
int num = cols.getNum() != null ? cols.getNum().intValue() : 1;
if (num <= 1) return totalWidthTwips;
int space = cols.getSpace() != null ? cols.getSpace().intValue() : 720; // 默认 0.5"
int width = totalWidthTwips - (num - 1) * space;
if (width <= 0) return totalWidthTwips;
return width / num;
}
// 节页面设置 - 纸张方向
public static String getSectionPageOrientation(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
PPr pPr = paragraph.getPPr();
@@ -286,20 +429,20 @@ public class SectionPage {
// ----- 奇数页眉 -----
//奇数页眉文本
public static String getOddHeaderText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddHeaderText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
return hfp.getDefaultHeader() != null ? extractHeaderInfo(hfp.getDefaultHeader(),wordMLPackage).text : null;
}
//奇数页眉字体
public static String getOddHeaderFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddHeaderFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
return hfp.getDefaultHeader() != null ? extractHeaderInfo(hfp.getDefaultHeader(),wordMLPackage).font : null;
}
//奇数页眉字号
public static String getOddHeaderFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddHeaderFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
HeaderInfo hi = hfp.getDefaultHeader() != null ? extractHeaderInfo(hfp.getDefaultHeader(),wordMLPackage) : null;
return (hi != null && hi.fontSizePt != null) ? hi.fontSizePt + " pt" : null;
}
//奇数页眉颜色
public static String getOddHeaderColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddHeaderColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getDefaultHeader() == null) {
return null;
}
@@ -308,13 +451,13 @@ public class SectionPage {
}
// 奇数页眉对齐方式
public static String getOddHeaderAlignment(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddHeaderAlignment(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
String align = hfp.getDefaultHeader() != null ? extractHeaderInfo(hfp.getDefaultHeader(),wordMLPackage).alignment : null;
return convertAlignToChinese(align);
}
//加粗
public static String getOddHeaderBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddHeaderBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getDefaultHeader() == null) {
return null;
}
@@ -322,7 +465,7 @@ public class SectionPage {
return bold;
}
//倾斜
public static String getOddHeaderItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddHeaderItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getDefaultHeader() == null) {
return null;
}
@@ -332,20 +475,20 @@ public class SectionPage {
// ----- 偶数页眉 -----
//偶数页眉文本
public static String getEvenHeaderText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenHeaderText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
return hfp.getEvenHeader() != null ? extractHeaderInfo(hfp.getEvenHeader(),wordMLPackage).text : null;
}
//偶数页眉字体
public static String getEvenHeaderFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenHeaderFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
return hfp.getEvenHeader() != null ? extractHeaderInfo(hfp.getEvenHeader(),wordMLPackage).font : null;
}
//偶数页眉字号
public static String getEvenHeaderFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenHeaderFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
HeaderInfo hi = hfp.getEvenHeader() != null ? extractHeaderInfo(hfp.getEvenHeader(),wordMLPackage) : null;
return (hi != null && hi.fontSizePt != null) ? hi.fontSizePt + " pt" : null;
}
//偶数页眉颜色
public static String getEvenHeaderColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenHeaderColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getEvenHeader() == null) {
return null;
}
@@ -354,12 +497,12 @@ public class SectionPage {
}
// 偶数页眉对齐方式
public static String getEvenHeaderAlignment(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenHeaderAlignment(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
String align = hfp.getEvenHeader() != null ? extractHeaderInfo(hfp.getEvenHeader(),wordMLPackage).alignment : null;
return convertAlignToChinese(align);
}
//加粗
public static String getEvenHeaderBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenHeaderBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getEvenHeader() == null) {
return null;
}
@@ -367,7 +510,7 @@ public class SectionPage {
return bold;
}
//倾斜
public static String getEvenHeaderItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenHeaderItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getEvenHeader() == null) {
return null;
}
@@ -376,20 +519,20 @@ public class SectionPage {
}
// ----- 首页眉 -----
//首页眉文本
public static String getFirstHeaderText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstHeaderText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
return hfp.getFirstHeader() != null ? extractHeaderInfo(hfp.getFirstHeader(),wordMLPackage).text : null;
}
//首页眉字体
public static String getFirstHeaderFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstHeaderFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
return hfp.getFirstHeader() != null ? extractHeaderInfo(hfp.getFirstHeader(),wordMLPackage).font : null;
}
//首页眉字号
public static String getFirstHeaderFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstHeaderFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
HeaderInfo hi = hfp.getFirstHeader() != null ? extractHeaderInfo(hfp.getFirstHeader(),wordMLPackage) : null;
return (hi != null && hi.fontSizePt != null) ? hi.fontSizePt + " pt" : null;
}
//首页眉颜色
public static String getFirstHeaderColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstHeaderColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getFirstHeader() == null) {
return null;
}
@@ -401,12 +544,12 @@ public class SectionPage {
}
// 首页眉对齐方式
public static String getFirstHeaderAlignment(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstHeaderAlignment(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
String align = hfp.getFirstHeader() != null ? extractHeaderInfo(hfp.getFirstHeader(),wordMLPackage).alignment : null;
return convertAlignToChinese(align);
}
//加粗
public static String getFirstHeaderBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstHeaderBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getFirstHeader() == null) {
return null;
}
@@ -414,7 +557,7 @@ public class SectionPage {
return bold;
}
//倾斜
public static String getFirstHeaderItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstHeaderItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getFirstHeader() == null) {
return null;
}
@@ -450,32 +593,32 @@ public class SectionPage {
}
// 奇数页
//字体
public static String getOddFooterFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddFooterFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getDefaultFooter() == null) return null;
HeaderInfo info = extractFooterInfo(hfp.getDefaultFooter(), wordMLPackage);
return info == null ? null : info.font;
}
//字号
public static String getOddFooterFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddFooterFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getDefaultFooter() == null) return null;
HeaderInfo info = extractFooterInfo(hfp.getDefaultFooter(), wordMLPackage);
return info == null ? null : String.valueOf(info.fontSizePt);
}
//对齐方式
public static String getOddFooterAlign(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddFooterAlign(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getDefaultFooter() == null) return null;
HeaderInfo info = extractFooterInfo(hfp.getDefaultFooter(), wordMLPackage);
return convertAlignToChinese(info.alignment);
}
//颜色
public static String getOddFooterColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddFooterColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getDefaultFooter() == null) return null;
String colorHex = extractFooterInfo(hfp.getDefaultFooter(),wordMLPackage).colorHex;
return pc.exam.pp.module.judgement.utils.wps_word.utils.ColorUtils.getChineseColorName(colorHex);
}
public static String getOddFooterText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddFooterText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getDefaultFooter() == null) return null;
String text = extractFooterInfo(hfp.getDefaultFooter(), wordMLPackage).text;
if (text==null){
@@ -487,7 +630,7 @@ public class SectionPage {
//加粗
public static String getOddFooterBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddFooterBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getDefaultFooter() == null) {
return null;
}
@@ -495,7 +638,7 @@ public class SectionPage {
return bold;
}
//倾斜
public static String getOddFooterItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getOddFooterItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getDefaultFooter() == null) {
return null;
}
@@ -507,36 +650,36 @@ public class SectionPage {
// 偶数页
//字体
public static String getEvenFooterFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenFooterFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getEvenFooter() == null) return null;
HeaderInfo info = extractFooterInfo(hfp.getEvenFooter(), wordMLPackage);
return info == null ? null : info.font;
}
//字号
public static String getEvenFooterFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenFooterFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getEvenFooter() == null) return null;
HeaderInfo info = extractFooterInfo(hfp.getEvenFooter(), wordMLPackage);
return String.valueOf(info == null ? null : info.fontSizePt);
}
public static String getEvenFooterAlign(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenFooterAlign(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getEvenFooter() == null) return null;
HeaderInfo info = extractFooterInfo(hfp.getEvenFooter(), wordMLPackage);
return convertAlignToChinese(info.alignment);
}
public static String getEvenFooterText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenFooterText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
return hfp.getEvenFooter() != null ? extractFooterInfo(hfp.getEvenFooter(),wordMLPackage).text : null;
}
//颜色
public static String getEvenFooterColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenFooterColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getEvenFooter() == null) return null;
String colorHex = extractFooterInfo(hfp.getEvenFooter(),wordMLPackage).colorHex;
return pc.exam.pp.module.judgement.utils.wps_word.utils.ColorUtils.getChineseColorName(colorHex);
}
//加粗
public static String getEvenFooterBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenFooterBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getEvenFooter() == null) {
return null;
}
@@ -544,7 +687,7 @@ public class SectionPage {
return bold;
}
//倾斜
public static String getEvenFooterItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getEvenFooterItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getEvenFooter() == null) {
return null;
}
@@ -552,34 +695,34 @@ public class SectionPage {
return italic;
}
// ===== 首页页脚 =====
public static String getFirstFooterFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstFooterFont(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getFirstFooter() == null) return null;
HeaderInfo info = extractFooterInfo(hfp.getFirstFooter(), wordMLPackage);
return info == null ? null : info.font;
}
public static String getFirstFooterFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstFooterFontSize(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getFirstFooter() == null) return null;
HeaderInfo info = extractFooterInfo(hfp.getFirstFooter(), wordMLPackage);
return info == null ? null : String.valueOf(info.fontSizePt);
}
public static String getFirstFooterAlign(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstFooterAlign(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getFirstFooter() == null) return null;
HeaderInfo info = extractFooterInfo(hfp.getFirstFooter(), wordMLPackage);
return convertAlignToChinese(info.alignment);
}
public static String getFirstFooterColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstFooterColor(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getFirstFooter() == null) return null;
String colorHex = extractFooterInfo(hfp.getFirstFooter(),wordMLPackage).colorHex;
return pc.exam.pp.module.judgement.utils.wps_word.utils.ColorUtils.getChineseColorName(colorHex);
}
public static String getFirstFooterText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstFooterText(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
return hfp.getFirstFooter() != null ? extractFooterInfo(hfp.getFirstFooter(),wordMLPackage).text : null;
}
//加粗
public static String getFirstFooterBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstFooterBold(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getFirstFooter() == null) {
return null;
}
@@ -587,7 +730,7 @@ public class SectionPage {
return bold;
}
//倾斜
public static String getFirstFooterItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
public static String getFirstFooterItalic(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) throws Docx4JException {
if (hfp.getFirstFooter() == null) {
return null;
}
@@ -641,25 +784,19 @@ public class SectionPage {
}
public static HeaderInfo extractFooterInfo(FooterPart footerPart, WordprocessingMLPackage wordMLPackage) {
public static HeaderInfo extractFooterInfo(FooterPart footerPart, WordprocessingMLPackage wordMLPackage) throws Docx4JException {
HeaderInfo info = new HeaderInfo();
StringBuilder textBuilder = new StringBuilder();
List<Object> contents = footerPart.getContent();
for (Object obj : contents) {
if (obj instanceof P) {
P paragraph = (P) obj;
PPr pPr = paragraph.getPPr();
String styleId = (pPr != null && pPr.getPStyle() != null) ? pPr.getPStyle().getVal() : null;
if (footerPart == null || footerPart.getContents() == null) {
return info;
}
Ftr ftr = footerPart.getContents();
// 对齐方式
if (pPr != null && pPr.getJc() != null) {
info.alignment = pPr.getJc().getVal().value();
}
for (Object o : paragraph.getContent()) {
extractTextFromContent(o, textBuilder, info, styleId, wordMLPackage);
}
for (Object block : ftr.getContent()) {
Object u = XmlUtils.unwrap(block);
if (u instanceof P) {
parseParagraph((P) u, info, textBuilder, wordMLPackage);
}
}
@@ -667,6 +804,208 @@ public class SectionPage {
return info;
}
private static void parseParagraph(P paragraph, HeaderInfo info, StringBuilder textBuilder, WordprocessingMLPackage pkg) {
// 对齐方式
if (paragraph.getPPr() != null && paragraph.getPPr().getJc() != null) {
info.alignment = paragraph.getPPr().getJc().getVal().value();
}
for (Object o : paragraph.getContent()) {
Object unwrapped = XmlUtils.unwrap(o);
if (unwrapped instanceof R) {
R run = (R) unwrapped;
// 先拿到 run 自己的样式(外层 w:rPr可能是 9pt、无色
applyRunStyle(run.getRPr(), info);
for (Object rc : run.getContent()) {
Object inner = XmlUtils.unwrap(rc);
if (inner instanceof Text) {
textBuilder.append(((Text) inner).getValue());
}
// 关键Run 里常见的是 AlternateContent而不是直接 Drawing
else if (inner instanceof AlternateContent) {
extractFromAlternateContent((AlternateContent) inner, info, textBuilder, pkg);
}
else if (inner instanceof Drawing) { // 少量文档会直接是 Drawing
extractFromDrawing((Drawing) inner, info, textBuilder, pkg);
}
else if (inner instanceof Pict) { // 旧版 VML fallback
extractFromPict((Pict) inner, info, textBuilder, pkg);
}
}
}
// 有些极端情况下,文本框会直接挂在段落(不是 run也处理一下
else if (unwrapped instanceof AlternateContent) {
extractFromAlternateContent((AlternateContent) unwrapped, info, textBuilder, pkg);
} else if (unwrapped instanceof Drawing) {
extractFromDrawing((Drawing) unwrapped, info, textBuilder, pkg);
} else if (unwrapped instanceof Pict) {
extractFromPict((Pict) unwrapped, info, textBuilder, pkg);
}
}
}
private static void extractFromAlternateContent(
AlternateContent ac,
HeaderInfo info,
StringBuilder textBuilder,
WordprocessingMLPackage pkg) {
// 处理 Choice 部分
for (AlternateContent.Choice choice : ac.getChoice()) {
for (Object any : choice.getAny()) {
Object child = XmlUtils.unwrap(any);
if (child instanceof Drawing) {
extractFromDrawing((Drawing) child, info, textBuilder, pkg);
} else if (child instanceof Pict) {
extractFromPict((Pict) child, info, textBuilder, pkg);
} else if (child instanceof P) {
// 如果里面直接有段落
extractFromParagraph((P) child, info, textBuilder, pkg);
}
}
}
// 处理 Fallback 部分
AlternateContent.Fallback fb = ac.getFallback();
if (fb != null) {
for (Object any : fb.getAny()) {
Object child = XmlUtils.unwrap(any);
if (child instanceof Drawing) {
extractFromDrawing((Drawing) child, info, textBuilder, pkg);
} else if (child instanceof Pict) {
extractFromPict((Pict) child, info, textBuilder, pkg);
} else if (child instanceof P) {
extractFromParagraph((P) child, info, textBuilder, pkg);
}
}
}
}
private static void extractFromParagraph(P p, HeaderInfo info, StringBuilder textBuilder, WordprocessingMLPackage pkg) {
if (p == null) return;
List<Object> contents = p.getContent();
for (Object o : contents) {
Object child = XmlUtils.unwrap(o);
if (child instanceof R) {
R run = (R) child;
for (Object rChild : run.getContent()) {
Object rObj = XmlUtils.unwrap(rChild);
// 普通文本
if (rObj instanceof Text) {
textBuilder.append(((Text) rObj).getValue());
}
// 域代码(页码等)也在 R 里面,但不用 InstrText直接抓文字
else if (rObj instanceof org.docx4j.wml.FldChar) {
// 可以加标记或忽略
}
// 文本框里的段落
else if (rObj instanceof P) {
extractFromParagraph((P) rObj, info, textBuilder, pkg);
}
// Drawing 或 Pict
else if (rObj instanceof Drawing) {
extractFromDrawing((Drawing) rObj, info, textBuilder, pkg);
} else if (rObj instanceof Pict) {
extractFromPict((Pict) rObj, info, textBuilder, pkg);
}
}
}
// 段落里嵌套文本框
else if (child instanceof org.docx4j.wml.Drawing) {
extractFromDrawing((Drawing) child, info, textBuilder, pkg);
} else if (child instanceof Pict) {
extractFromPict((Pict) child, info, textBuilder, pkg);
}
}
}
private static void extractFromDrawing(Drawing drawing, HeaderInfo info, StringBuilder textBuilder, WordprocessingMLPackage pkg) {
try {
// 为了兼容 wps:wsp / wps:txbx直接把 Drawing 序列化,再找 <w:txbxContent> 里的 <w:p>
String xml = XmlUtils.marshaltoString(drawing, true, true);
extractTxbxParagraphsFromXml(xml, info, textBuilder, pkg);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void extractFromPict(Pict pict, HeaderInfo info, StringBuilder textBuilder, WordprocessingMLPackage pkg) {
try {
// 旧版 VML 文本框:<w:pict><v:shape>...<w:txbxContent><w:p>...</w:p>
String xml = XmlUtils.marshaltoString(pict, true, true);
extractTxbxParagraphsFromXml(xml, info, textBuilder, pkg);
} catch (Exception e) {
e.printStackTrace();
}
}
/** 从包含 <w:txbxContent> 的 XML 里把内部 <w:p> 反序列化出来再递归解析(获取真正字号/颜色/加粗等) */
private static void extractTxbxParagraphsFromXml(String xml, HeaderInfo info, StringBuilder textBuilder, WordprocessingMLPackage pkg) throws Exception {
org.w3c.dom.Document doc = XmlUtils.getNewDocumentBuilder()
.parse(new java.io.ByteArrayInputStream(xml.getBytes(java.nio.charset.StandardCharsets.UTF_8)));
// 只在 <w:txbxContent> 下面找 <w:p>
final String W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
org.w3c.dom.NodeList txbxList = doc.getElementsByTagNameNS(W_NS, "txbxContent");
for (int i = 0; i < txbxList.getLength(); i++) {
org.w3c.dom.Node txbx = txbxList.item(i);
org.w3c.dom.NodeList children = txbx.getChildNodes();
for (int j = 0; j < children.getLength(); j++) {
org.w3c.dom.Node node = children.item(j);
if (W_NS.equals(node.getNamespaceURI()) && "p".equals(node.getLocalName())) {
String pXml = XmlUtils.w3CDomNodeToString(node);
P innerP = (P) XmlUtils.unmarshalString(pXml);
// 这里会读取到真正的 rPr<w:color FF0000/>、<w:sz 28/>、<w:b/>
parseParagraph(innerP, info, textBuilder, pkg);
}
}
}
}
private static void applyRunStyle(RPr rPr, HeaderInfo info) {
if (rPr == null) return;
// 字体
if (rPr.getRFonts() != null) {
if (rPr.getRFonts().getEastAsia() != null && !rPr.getRFonts().getEastAsia().isEmpty()) {
info.font = rPr.getRFonts().getEastAsia(); // 中文字体
} else if (rPr.getRFonts().getAscii() != null && !rPr.getRFonts().getAscii().isEmpty()) {
info.font = rPr.getRFonts().getAscii(); // 英文字体
}
}
// 字号
if (rPr.getSz() != null && rPr.getSz().getVal() != null) {
info.fontSizePt = rPr.getSz().getVal().doubleValue() / 2.0;
}
// 颜色
if (rPr.getColor() != null && rPr.getColor().getVal() != null && !rPr.getColor().getVal().isEmpty()) {
info.colorHex = rPr.getColor().getVal();
}
// 加粗
if (rPr.getB() != null && rPr.getB().isVal()) {
info.bold = "";
}
// 倾斜
if (rPr.getI() != null && rPr.getI().isVal()) {
info.italic = "";
}
}
/**
* 递归解析内容,包括文本框里的段落
@@ -1129,8 +1468,11 @@ public class SectionPage {
//节 页面设置(纸张大小) 纸型
public static String getPageSetType(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
// 节 页面设置(纸张大小) 纸型
// 节 页面设置(纸张大小) 纸型
public static String getPageSetType(P paragraph, HeaderFooterPolicy hfp,
WordprocessingMLPackage wordMLPackage,
List<SectionWrapper> sections) {
// 获取段落所在节的 SectPr
SectPr currentSectPr = null;
@@ -1161,19 +1503,57 @@ public class SectionPage {
SectPr.PgSz pgSz = currentSectPr.getPgSz();
BigInteger w = pgSz.getW();
BigInteger h = pgSz.getH();
// 常用纸张判断 (宽 x 高, 单位 twip)
if (w != null && h != null) {
if ((w.equals(BigInteger.valueOf(11906)) && h.equals(BigInteger.valueOf(16838)))||(h.equals(BigInteger.valueOf(11906)) && w.equals(BigInteger.valueOf(16838)))) return "A4";
if ((w.equals(BigInteger.valueOf(16838)) && h.equals(BigInteger.valueOf(23811))) ||((h.equals(BigInteger.valueOf(16838)) && w.equals(BigInteger.valueOf(23811))) )) return "A3";
if ((w.equals(BigInteger.valueOf(8504)) && h.equals(BigInteger.valueOf(11906)))||(h.equals(BigInteger.valueOf(8504)) && w.equals(BigInteger.valueOf(11906)))) return "B5";
if ((w.equals(BigInteger.valueOf(23811)) && h.equals(BigInteger.valueOf(33685)))||(h.equals(BigInteger.valueOf(23811)) && w.equals(BigInteger.valueOf(33685)))) return "A2";
if ((w.equals(BigInteger.valueOf(11906)) && h.equals(BigInteger.valueOf(16838)))||(h.equals(BigInteger.valueOf(11906)) && w.equals(BigInteger.valueOf(16838)))) return "Letter"; // 可根据需要补充
if (w == null || h == null) {
return "未知纸张";
}
// 允许 ±5 的误差
final int tol = 5;
int width = w.intValue();
int height = h.intValue();
System.out.println(width);
System.out.println(height);
// 宽高标准值 (单位 twip)
Map<String, int[]> standard = new HashMap<>();
standard.put("A3", new int[]{16838, 23811});
standard.put("A4", new int[]{11906, 16838});
standard.put("A5", new int[]{8391, 11906});
standard.put("B4", new int[]{14572, 20638});
standard.put("B5", new int[]{10319, 14572});
standard.put("16开", new int[]{10433, 14742}); // 印刷厂常用尺寸 184×260mm
standard.put("国标16开", new int[]{8338, 11906}); // 国标16开 147×210mm
standard.put("32开", new int[]{7371, 10433}); // 你提供的
standard.put("大32开", new int[]{7938, 11510});
standard.put("Statement", new int[]{7920, 12240});
standard.put("Executive", new int[]{10440, 15120});
standard.put("Letter(信纸)", new int[]{12240, 15840});
standard.put("Tabloid", new int[]{15840, 24480});
standard.put("Legal(法律纸)", new int[]{12240, 20160});
for (Map.Entry<String, int[]> entry : standard.entrySet()) {
int sw = entry.getValue()[0];
int sh = entry.getValue()[1];
// 纵向匹配
if (Math.abs(width - sw) <= tol && Math.abs(height - sh) <= tol) {
return entry.getKey();
}
// 横向匹配
if (Math.abs(width - sh) <= tol && Math.abs(height - sw) <= tol) {
return entry.getKey() + " (横向)";
}
}
return "自定义纸张";
}
//宽度
public static String getPageSetWidth(P paragraph, HeaderFooterPolicy hfp, WordprocessingMLPackage wordMLPackage, List<SectionWrapper> sections) {
MainDocumentPart mainPart = wordMLPackage.getMainDocumentPart();
@@ -1513,68 +1893,19 @@ public class SectionPage {
}
}
}
public static HeaderInfo extractHeaderInfo(HeaderPart headerPart,WordprocessingMLPackage wordMLPackage) {
public static HeaderInfo extractHeaderInfo(HeaderPart headerPart,WordprocessingMLPackage wordMLPackage) throws Docx4JException {
HeaderInfo info = new HeaderInfo();
StringBuilder textBuilder = new StringBuilder();
List<Object> contents = headerPart.getContent();
for (Object obj : contents) {
if (obj instanceof P) {
P paragraph = (P) obj;
// 先获取段落样式id
PPr pPr = paragraph.getPPr();
String styleId = (pPr != null && pPr.getPStyle() != null) ? pPr.getPStyle().getVal() : null;
// 对齐方式
if (paragraph.getPPr() != null && paragraph.getPPr().getJc() != null) {
info.alignment = paragraph.getPPr().getJc().getVal().value();
}
if (headerPart == null || headerPart.getContents() == null) {
return info;
}
Hdr ftr = headerPart.getContents();
for (Object o : paragraph.getContent()) {
if (o instanceof R) {
R run = (R) o;
RPr rPr = run.getRPr();
if (rPr != null) {
// 取字体
if (info.font == null) {
info.font = getFontFromRunOrStyle(rPr, styleId, wordMLPackage);
}
// if (info.fontSizePt == null) {
// info.fontSizePt = getFontSizeNameByRunAndStyles(run, wordMLPackage);
// if (info.fontSizePt == null) {
// // 样式查不到就直接从Run获取字号数字
// info.fontSizePt = getFontSizeFromRun(run);
// }
//
// }
// 取字号
if (info.fontSizePt == null) {
info.fontSizePt = getFontSizeFromRunOrStyle(rPr, styleId, wordMLPackage);
}
if (rPr.getColor() != null) {
info.colorHex = rPr.getColor().getVal();
}
// 加粗
info.bold = (rPr.getB() != null && Boolean.TRUE.equals(rPr.getB().isVal())) ? "" : "";
// 倾斜
info.italic = (rPr.getI() != null && Boolean.TRUE.equals(rPr.getI().isVal())) ? "" : "";
}
// 取文字内容
for (Object rContent : run.getContent()) {
Object val = (rContent instanceof JAXBElement)
? ((JAXBElement<?>) rContent).getValue()
: rContent;
if (val instanceof Text) {
textBuilder.append(((Text) val).getValue());
}
}
}
}
for (Object block : ftr.getContent()) {
Object u = XmlUtils.unwrap(block);
if (u instanceof P) {
parseParagraph((P) u, info, textBuilder, wordMLPackage);
}
}