mirror of
https://gitee.com/dromara/hutool.git
synced 2025-06-28 13:34:09 +08:00
Pre Merge pull request !1311 from Nicely/v5-dev
This commit is contained in:
commit
383524aca2
@ -6,19 +6,22 @@ import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.poi.exceptions.POIException;
|
||||
import cn.hutool.poi.word.style.Bracket;
|
||||
import cn.hutool.poi.word.style.StyleUtil;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFRun;
|
||||
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
|
||||
import org.apache.poi.xwpf.usermodel.*;
|
||||
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.*;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Word docx生成器
|
||||
@ -29,6 +32,12 @@ import java.io.OutputStream;
|
||||
public class Word07Writer implements Closeable {
|
||||
|
||||
private final XWPFDocument doc;
|
||||
|
||||
/**
|
||||
* 页眉页脚策略
|
||||
*/
|
||||
protected XWPFHeaderFooterPolicy headerFooterPolicy;
|
||||
|
||||
/**
|
||||
* 目标文件
|
||||
*/
|
||||
@ -70,6 +79,7 @@ public class Word07Writer implements Closeable {
|
||||
public Word07Writer(XWPFDocument doc, File destFile) {
|
||||
this.doc = doc;
|
||||
this.destFile = destFile;
|
||||
this.headerFooterPolicy = null;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------- Constructor end
|
||||
@ -94,6 +104,21 @@ public class Word07Writer implements Closeable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个新的段落
|
||||
*
|
||||
* @param alignment 段落对齐方式 {@link ParagraphAlignment}
|
||||
* @return XWPFParagraph
|
||||
* @since 5.8.37
|
||||
*/
|
||||
public XWPFParagraph addParagraph(ParagraphAlignment alignment) {
|
||||
XWPFParagraph paragraph = this.doc.createParagraph();
|
||||
if (null != alignment) {
|
||||
paragraph.setAlignment(alignment);
|
||||
}
|
||||
return paragraph;
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加一个段落
|
||||
*
|
||||
@ -134,6 +159,173 @@ public class Word07Writer implements Closeable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定段落添加一行文本
|
||||
*
|
||||
* @param paragraph 指定段落 {@link XWPFParagraph}
|
||||
* @param font 字体信息{@link Font}
|
||||
* @param text 段落中的文本
|
||||
* @return row
|
||||
* @since 5.8.37
|
||||
*/
|
||||
public XWPFRun addRun(XWPFParagraph paragraph, Font font, String text) {
|
||||
XWPFRun run = paragraph.createRun();
|
||||
run.setText(text);
|
||||
if (null != font) {
|
||||
run.setFontFamily(font.getFamily());
|
||||
run.setFontSize(font.getSize());
|
||||
run.setBold(font.isBold());
|
||||
run.setItalic(font.isItalic());
|
||||
}
|
||||
return run;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定行添加尾注
|
||||
*
|
||||
* @param run 指定文本行 {@link XWPFRun}
|
||||
* @param endNoteText 尾注说明
|
||||
* @param bracket 标识样式 {@link Bracket}
|
||||
* @return this
|
||||
* @since 5.8.37
|
||||
*/
|
||||
public Word07Writer addEndNotesToRun(XWPFRun run, String endNoteText, Bracket bracket){
|
||||
CTFtnEdnRef fr = run.getCTR().addNewEndnoteReference();
|
||||
fr.setId(BigInteger.ONE);
|
||||
this.doc.createEndnotes();
|
||||
CTFtnEdn ctNote = CTFtnEdn.Factory.newInstance();
|
||||
ctNote.setId(BigInteger.ONE);
|
||||
ctNote.setType(STFtnEdn.NORMAL);
|
||||
CTP ctp = ctNote.addNewP();
|
||||
XWPFParagraph p2 = new XWPFParagraph(ctp, this.doc);
|
||||
|
||||
if (null != bracket) {
|
||||
if (bracket != Bracket.NONE){
|
||||
run = p2.createRun();
|
||||
run.setText(bracket.getPrefix());
|
||||
}
|
||||
}
|
||||
|
||||
run = p2.createRun();
|
||||
run.getCTR().addNewEndnoteRef();
|
||||
|
||||
if (null != bracket) {
|
||||
if (bracket != Bracket.NONE){
|
||||
run = p2.createRun();
|
||||
run.setText(bracket.getSuffix());
|
||||
}
|
||||
}
|
||||
CTText ctText = run.getCTR().addNewT();
|
||||
ctText.setStringValue(" ");
|
||||
ctText.setSpace(SpaceAttribute.Space.PRESERVE);
|
||||
run.setText(endNoteText);
|
||||
this.doc.addEndnote(ctNote);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定行添加脚注
|
||||
*
|
||||
* @param run 指定文本行 {@link XWPFRun}
|
||||
* @param footNoteText 脚注说明文本
|
||||
* @param bracket 标识样式 {@link Bracket}
|
||||
*
|
||||
* @return this
|
||||
* @since 5.8.37
|
||||
*/
|
||||
public Word07Writer addFootNotesToRun(XWPFRun run, String footNoteText, Bracket bracket) {
|
||||
CTFtnEdnRef fr = run.getCTR().addNewFootnoteReference();
|
||||
fr.setId(BigInteger.ONE);
|
||||
|
||||
XWPFFootnotes footnotes = this.doc.createFootnotes();
|
||||
CTFtnEdn ctNote = CTFtnEdn.Factory.newInstance();
|
||||
ctNote.setId(BigInteger.ONE);
|
||||
ctNote.setType(STFtnEdn.NORMAL);
|
||||
CTP ctp = ctNote.addNewP();
|
||||
|
||||
XWPFParagraph xwpfParagraph = new XWPFParagraph(ctp, this.doc);
|
||||
|
||||
if (null != bracket) {
|
||||
if (bracket != Bracket.NONE){
|
||||
run = xwpfParagraph.createRun();
|
||||
run.setText(bracket.getPrefix());
|
||||
}
|
||||
}
|
||||
run = xwpfParagraph.createRun();
|
||||
run.getCTR().addNewFootnoteRef();
|
||||
|
||||
if (null != bracket) {
|
||||
if (bracket != Bracket.NONE){
|
||||
run = xwpfParagraph.createRun();
|
||||
run.setText(bracket.getSuffix());
|
||||
}
|
||||
}
|
||||
|
||||
run = xwpfParagraph.createRun();
|
||||
CTText ctText = run.getCTR().addNewT();
|
||||
ctText.setStringValue(" ");
|
||||
ctText.setSpace(SpaceAttribute.Space.PRESERVE);
|
||||
run.setText(footNoteText);
|
||||
footnotes.addFootnote(ctNote);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为文档添加页眉
|
||||
*
|
||||
* @param alignment 页眉位置 {@link ParagraphAlignment}
|
||||
* @param font 页眉样式 {@link Font}
|
||||
* @param headerText 页脚内容
|
||||
* @return this
|
||||
* @since 5.8.37
|
||||
*/
|
||||
public Word07Writer addHeader(ParagraphAlignment alignment, Font font, String headerText) {
|
||||
if (null == this.headerFooterPolicy) {
|
||||
this.headerFooterPolicy = this.doc.createHeaderFooterPolicy();
|
||||
}
|
||||
XWPFHeader header = this.headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);
|
||||
XWPFParagraph headerParagraph = header.createParagraph();
|
||||
if (null != alignment) {
|
||||
headerParagraph.setAlignment(alignment);
|
||||
}
|
||||
addRun(headerParagraph, font, headerText);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为文档添加页脚
|
||||
*
|
||||
* @param alignment 页脚位置 {@link ParagraphAlignment}
|
||||
* @param font 页脚样式 {@link Font}
|
||||
* @param footerText 页脚内容
|
||||
* @return this
|
||||
* @since 5.8.37
|
||||
*/
|
||||
public Word07Writer addFooter(ParagraphAlignment alignment, Font font, String footerText) {
|
||||
if (null == this.headerFooterPolicy) {
|
||||
this.headerFooterPolicy = this.doc.createHeaderFooterPolicy();
|
||||
}
|
||||
XWPFFooter footer = this.headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT);
|
||||
XWPFParagraph footerParagraph = footer.createParagraph();
|
||||
if (null != alignment) {
|
||||
footerParagraph.setAlignment(ParagraphAlignment.CENTER);
|
||||
}
|
||||
addRun(footerParagraph, font, footerText);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新开一页
|
||||
*
|
||||
* @return this
|
||||
* @since 5.8.37
|
||||
*/
|
||||
public Word07Writer newPage() {
|
||||
XWPFParagraph newPageParagraph = this.doc.createParagraph();
|
||||
newPageParagraph.setPageBreak(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加表格数据
|
||||
*
|
||||
|
@ -0,0 +1,44 @@
|
||||
package cn.hutool.poi.word.style;
|
||||
|
||||
/**
|
||||
* 脚注尾注括号枚举
|
||||
*
|
||||
* @author nicely🍊
|
||||
* @since 5.8.37
|
||||
*/
|
||||
public enum Bracket {
|
||||
|
||||
/**
|
||||
* 无额外标识
|
||||
*/
|
||||
NONE(null, null),
|
||||
/**
|
||||
* 大括号
|
||||
*/
|
||||
BRACES("{", "}"),
|
||||
/**
|
||||
* 中括号
|
||||
*/
|
||||
BRACKETS("[", "]"),
|
||||
/**
|
||||
* 小括号
|
||||
*/
|
||||
PARENTHESES("(", ")");
|
||||
|
||||
private final String prefix;
|
||||
private final String suffix;
|
||||
|
||||
Bracket(String prefix, String suffix) {
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package cn.hutool.poi.word.style;
|
||||
|
||||
import org.apache.poi.xwpf.usermodel.XWPFRun;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Docx样式工具类
|
||||
*
|
||||
* @author nicely🍊
|
||||
* @since 5.8.37
|
||||
*/
|
||||
public class StyleUtil {
|
||||
|
||||
/**
|
||||
* 为文本设置样式
|
||||
* @param run 指定文本 {@link XWPFRun}
|
||||
* @param font 字体 {@link Font}
|
||||
* @param rgb 文本颜色(rgb色值 ex: FF0000)
|
||||
* @param isUnderLine 是否启用下划线
|
||||
* @param underLineColor 下划线颜色 (rgb)
|
||||
* @param underLineStyle 下划线样式 (0:无, 1:实线, >1: 值越大虚线间隔越大)
|
||||
* @param isHighlight 是否启用高亮
|
||||
* @param highlightValue 高亮背景色 {@link STHighlightColor.Enum}
|
||||
* @param stRunEnum 垂直对齐方式 {@link STVerticalAlignRun.Enum}
|
||||
*
|
||||
* @since 5.8.37
|
||||
*/
|
||||
public static void setRunStyle(XWPFRun run, Font font, String rgb, boolean isUnderLine, String underLineColor,
|
||||
int underLineStyle, boolean isHighlight, STHighlightColor.Enum highlightValue,
|
||||
STVerticalAlignRun.Enum stRunEnum) {
|
||||
CTRPr pRpr = null;
|
||||
if (run.getCTR() != null) {
|
||||
pRpr = run.getCTR().getRPr();
|
||||
if (pRpr == null) {
|
||||
pRpr = run.getCTR().addNewRPr();
|
||||
}
|
||||
}
|
||||
|
||||
assert pRpr != null;
|
||||
if (null != font) {
|
||||
// 设置字体
|
||||
run.setFontFamily(font.getFamily());
|
||||
run.setFontSize(font.getSize());
|
||||
run.setBold(font.isBold());
|
||||
run.setItalic(font.isItalic());
|
||||
}
|
||||
|
||||
// 设置颜色
|
||||
if (null != rgb) {
|
||||
run.setColor(rgb);
|
||||
}
|
||||
|
||||
// 设置下划线样式
|
||||
if (isUnderLine) {
|
||||
CTUnderline u = pRpr.isSetU() ? pRpr.getU() : pRpr.addNewU();
|
||||
u.setVal(STUnderline.Enum.forInt(Math.abs(underLineStyle % 19)));
|
||||
if (underLineColor != null) {
|
||||
u.setColor(underLineColor);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置突出显示文本
|
||||
if (isHighlight) {
|
||||
CTHighlight highlight = pRpr.isSetHighlight() ? pRpr
|
||||
.getHighlight() : pRpr.addNewHighlight();
|
||||
highlight.setVal(highlightValue);
|
||||
}
|
||||
|
||||
if (stRunEnum != null) {
|
||||
CTVerticalAlignRun ctV = CTVerticalAlignRun.Factory.newInstance();
|
||||
ctV.setVal(stRunEnum);
|
||||
pRpr.setVertAlign(ctV);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* DOCX样式封装,入口为:StyleUtil
|
||||
*
|
||||
* @author nicely🍊
|
||||
*
|
||||
*/
|
||||
package cn.hutool.poi.word.style;
|
@ -5,10 +5,17 @@ import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.poi.word.style.Bracket;
|
||||
import cn.hutool.poi.word.style.StyleUtil;
|
||||
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFRun;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHighlightColor;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -95,4 +102,66 @@ public class WordWriterTest {
|
||||
word07Writer.addTable(list);
|
||||
word07Writer.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void endNotesTest() {
|
||||
final Word07Writer word07Writer = new Word07Writer();
|
||||
// 添加其他文本
|
||||
word07Writer.addText(ParagraphAlignment.CENTER, new Font("宋体", Font.BOLD, 12), "《野步》(唐)齐己");
|
||||
word07Writer.addText(ParagraphAlignment.CENTER, new Font("宋体", Font.PLAIN, 12), "城里无闲处,却寻城外行。田园经雨水,乡国忆桑耕。");
|
||||
|
||||
// 创建新段落
|
||||
XWPFParagraph paragraph = word07Writer.addParagraph(ParagraphAlignment.CENTER);
|
||||
// 为段落添加一行文本
|
||||
XWPFRun run = word07Writer.addRun(paragraph, new Font("宋体", Font.PLAIN, 12), "傍涧蕨薇老,隔村冈陇横。何穷此心兴,时复鹧鸪声。");
|
||||
// 为行文本添加尾注
|
||||
word07Writer.addEndNotesToRun(run, "石夫、韩新愚编著.不可不知的中华24节气常识[M].郑州:中原农民出版社,2010.09:49—50.", Bracket.BRACKETS);
|
||||
word07Writer.flush(FileUtil.file("e:/test/end_notes.docx"));
|
||||
word07Writer.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void footerTest() {
|
||||
final Word07Writer word07Writer = new Word07Writer();
|
||||
word07Writer.addFooter(ParagraphAlignment.CENTER, new Font("宋体", Font.BOLD, 12), "页脚");
|
||||
word07Writer.flush(FileUtil.file("e:/test/footer.docx"));
|
||||
word07Writer.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void headerTest() {
|
||||
final Word07Writer word07Writer = new Word07Writer();
|
||||
word07Writer.addHeader(ParagraphAlignment.CENTER, new Font("宋体", Font.BOLD, 12), "页眉");
|
||||
word07Writer.flush(FileUtil.file("e:/test/header.docx"));
|
||||
word07Writer.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void footerNotesTest() {
|
||||
final Word07Writer word07Writer = new Word07Writer();
|
||||
// 添加其他文本
|
||||
word07Writer.addText(ParagraphAlignment.CENTER, new Font("宋体", Font.BOLD, 14), "《野步》(唐)齐己");
|
||||
word07Writer.addText(ParagraphAlignment.CENTER, new Font("宋体", Font.PLAIN, 14), "城里无闲处,却寻城外行。田园经雨水,乡国忆桑耕。");
|
||||
|
||||
// 创建新段落
|
||||
XWPFParagraph paragraph = word07Writer.addParagraph(ParagraphAlignment.CENTER);
|
||||
// 为段落添加一行文本
|
||||
XWPFRun run1 = word07Writer.addRun(paragraph, null, "傍涧蕨薇老,隔村冈陇横。");
|
||||
// 为文本设置样式
|
||||
StyleUtil.setRunStyle(run1, new Font("宋体", Font.PLAIN, 14), "FF0000", true,
|
||||
"000000", 1, true, STHighlightColor.DARK_GRAY, STVerticalAlignRun.BASELINE);
|
||||
// 为行文本添加脚注
|
||||
word07Writer.addFootNotesToRun(run1, "石夫、韩新愚编著.不可不知的中华24节气常识[M]", Bracket.NONE);
|
||||
|
||||
XWPFRun run2 = word07Writer.addRun(paragraph, new Font("宋体", Font.PLAIN, 14), "何穷此心兴,时复鹧鸪声。");
|
||||
word07Writer.addFootNotesToRun(run2, "郑州:中原农民出版社,2010.09:49—50.", Bracket.BRACKETS);
|
||||
|
||||
word07Writer.flush(FileUtil.file("e:/test/footer_notes.docx"));
|
||||
word07Writer.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
hutool-poi/src/test/resources/end_notes.docx
Normal file
BIN
hutool-poi/src/test/resources/end_notes.docx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user