需求:有一个可修改属性样式的模板表格,然后生成的word文档中所有的表格的属性都使用该模板表格的属性样式。
本质就是获取二个参数,一个模板表格的html和自定义表格的html,全部转化为string类型。
模板表格:
自定义表格:
废话不说直接上代码:
/**
* 复制模板的样式到自定义表格
* @param content
* @param template
* @return
*/
private String copyStyleToCustomForm(String content, String template){
Document table = Jsoup.parse(content);
Document templateDocument = Jsoup.parse(template);
Element templateTable = templateDocument.getElementsByTag("table").first();
//获取第一行的tr,作为模板(第一行是标题)
Element titleRowTemplate = templateDocument.getElementsByTag("tr").first();
//获取标题的第一个th,作为模板(支持td标签标题的情况)
Element titleRowElementTemplate = titleRowTemplate.getElementsByTag("th").first();
if (titleRowElementTemplate == null){
titleRowElementTemplate = titleRowTemplate.getElementsByTag("td").first();
}
Element contentRowTemplate = templateDocument.getElementsByTag("tr").get(1);
//获取内容的第一个td,作为模板
Element contentRowElementTemplate = contentRowTemplate.getElementsByTag("td").first();
//移除table标签的属性
removeAttrs(table);
//添加模板table标签的属性
addAttrs(table, templateTable.attributes(), 0);
//复制标题的样式
copyThStyle(table, titleRowElementTemplate);
//复制表格内容的样式
copyTdStyle(table, contentRowElementTemplate);
return table.body().children().outerHtml();
}
其中包含的几个子方法如下,可以一起放在同一个工具类中:
/**
* 移除属性(rowspan和colspan除外)
* @param element
*/
private void removeAttrs(Element element){
Set<String> set = element.attributes().asList().stream().map(Attribute::getKey).collect(Collectors.toSet());
for (String key : set) {
if (!StringUtils.equals(key, "rowspan") && !StringUtils.equals(key, "colspan")){
element.removeAttr(key);
}
}
}
/**
* 添加属性
* @param element html 标签
* @param templateAttrs
* @param width
*/
private void addAttrs(Element element, Attributes templateAttrs, double width) {
for (Attribute attr : templateAttrs) {
String value = attr.getValue();
if (StringUtils.equals("style", attr.getKey())){
//style 中有多个属性控制,根据分号切割然后遍历处理
String[] split = attr.getValue().split(";");
for (int i = 0; i < split.length; i++) {
String key = split[i];
if (key.trim().startsWith("width")){
if (width != 0){
split[i] = "width: 14.9532%";
}
}
}
value = String.join(";",split);
}
element.attr(attr.getKey(), value);
}
}
/**
* 复制标题的样式
* @param table
* @param titleRowElementTemplate
*/
private void copyThStyle(Document table, Element titleRowElementTemplate) {
//通过自定义表格的第一行,判断它的宽度
Element tr = table.getElementsByTag("tr").get(0);
Elements tds = tr.getElementsByTag("td");
double width = 100D / tds.size();
for (Element th : tds) {
removeAttrs(th);
addAttrs(th, titleRowElementTemplate.attributes(), width);
Element cloneTd = titleRowElementTemplate.clone();
String value = th.text();
cloneTd.html(cloneTd.html().replace("{表头}", value));
th.html(cloneTd.html());
}
}
/**
* 复制表格内容的样式
* @param table
* @param contentRowElementTemplate
*/
private void copyTdStyle(Document table, Element contentRowElementTemplate) {
double width = getWidth(table);
Elements trs = table.getElementsByTag("tr");
//跳过第一个tr(跳过标题),遍历每一行(除去标题)
for (int i = 1; i < trs.size(); i++) {
Element tr = trs.get(i);
//遍历每一行里面的元素
for (Element td : tr.getElementsByTag("td")) {
removeAttrs(td);
addAttrs(td, contentRowElementTemplate.attributes(), width);
Element cloneTd = contentRowElementTemplate.clone();
String value = td.text();
cloneTd.html(cloneTd.html().replace("{内容}", value));
td.html(cloneTd.html());
}
}
}
/**
* 获取表格中单元格的宽度(百分比)
* @param table
* @return
*/
private double getWidth(Document table) {
//获取自定义表格的第二行,即内容行,再计算td的宽度
Element tr = table.getElementsByTag("tr").get(1);
Elements tds = tr.getElementsByTag("td");
return 100D / tds.size();
}