Compare commits

...

4 Commits

Author SHA1 Message Date
Looly
a56d2c03dc fix code 2025-11-26 23:35:28 +08:00
Looly
d9cbb19460 修复Word07Writerrun.setColor()的颜色十六进制转换逻辑(pr#4164@Github) 2025-11-26 20:33:56 +08:00
Golden Looly
f18a2b512f
Merge pull request #4164 from CherryRum/fix/set-color-argb
fix(Word07Writer): strip alpha channel from color and update tests
2025-11-26 20:32:48 +08:00
yulin
6fcd1a2603 fix(Word07Writer): strip alpha channel from color and update tests 2025-11-26 20:23:09 +08:00
4 changed files with 40 additions and 25 deletions

View File

@ -35,6 +35,7 @@
* 【core 】 修复`StrUtil.str(ByteBuffer, Charset)` 方法修改入参 `ByteBuffer``position`,导致入参变化 pr#4153@Github * 【core 】 修复`StrUtil.str(ByteBuffer, Charset)` 方法修改入参 `ByteBuffer``position`,导致入参变化 pr#4153@Github
* 【core 】 修复`ReflectUtil.newInstanceIfPossible`传入Object逻辑错误pr#4160@Github * 【core 】 修复`ReflectUtil.newInstanceIfPossible`传入Object逻辑错误pr#4160@Github
* 【core 】 修复`DateModifier`处理AM和PM的ceiling和round问题pr#4161@Github * 【core 】 修复`DateModifier`处理AM和PM的ceiling和round问题pr#4161@Github
* 【poi 】 修复`Word07Writer`run.setColor()的颜色十六进制转换逻辑pr#4164@Github
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.8.41(2025-10-12) # 5.8.41(2025-10-12)

View File

@ -79,7 +79,7 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
/** /**
* 自定义需要处理的sheet编号如果-1表示处理所有sheet * 自定义需要处理的sheet编号如果-1表示处理所有sheet
*/ */
private int rid = -1; private int sheetIndex = -1;
/** /**
* sheet名称主要用于使用sheet名读取的情况 * sheet名称主要用于使用sheet名读取的情况
*/ */
@ -132,7 +132,7 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
* @throws POIException IO异常包装 * @throws POIException IO异常包装
*/ */
public Excel03SaxReader read(POIFSFileSystem fs, String idOrRidOrSheetName) throws POIException { public Excel03SaxReader read(POIFSFileSystem fs, String idOrRidOrSheetName) throws POIException {
this.rid = getSheetIndex(idOrRidOrSheetName); this.sheetIndex = getSheetIndex(idOrRidOrSheetName);
formatListener = new FormatTrackingHSSFListener(new MissingRecordAwareHSSFListener(this)); formatListener = new FormatTrackingHSSFListener(new MissingRecordAwareHSSFListener(this));
final HSSFRequest request = new HSSFRequest(); final HSSFRequest request = new HSSFRequest();
@ -162,7 +162,7 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
* @return sheet序号 * @return sheet序号
*/ */
public int getSheetIndex() { public int getSheetIndex() {
return this.rid; return this.sheetIndex;
} }
/** /**
@ -175,8 +175,8 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
return this.sheetName; return this.sheetName;
} }
if (this.boundSheetRecords.size() > this.rid) { if (this.boundSheetRecords.size() > this.sheetIndex) {
return this.boundSheetRecords.get(this.rid > -1 ? this.rid : this.curRid).getSheetname(); return this.boundSheetRecords.get(this.sheetIndex > -1 ? this.sheetIndex : this.curRid).getSheetname();
} }
return null; return null;
@ -189,7 +189,7 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
*/ */
@Override @Override
public void processRecord(Record record) { public void processRecord(Record record) {
if (this.rid > -1 && this.curRid > this.rid) { if (this.sheetIndex > -1 && this.curRid > this.sheetIndex) {
// 指定Sheet之后的数据不再处理 // 指定Sheet之后的数据不再处理
return; return;
} }
@ -200,7 +200,7 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
boundSheetRecords.add(boundSheetRecord); boundSheetRecords.add(boundSheetRecord);
final String currentSheetName = boundSheetRecord.getSheetname(); final String currentSheetName = boundSheetRecord.getSheetname();
if(null != this.sheetName && StrUtil.equals(this.sheetName, currentSheetName)){ if(null != this.sheetName && StrUtil.equals(this.sheetName, currentSheetName)){
this.rid = this.boundSheetRecords.size() -1; this.sheetIndex = this.boundSheetRecords.size() -1;
} }
} else if (record instanceof SSTRecord) { } else if (record instanceof SSTRecord) {
// 静态字符串表 // 静态字符串表
@ -215,7 +215,7 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
curRid++; curRid++;
} }
} else if (record instanceof EOFRecord){ } else if (record instanceof EOFRecord){
if(this.rid < 0 && null != this.sheetName){ if(this.sheetIndex < 0 && null != this.sheetName){
throw new POIException("Sheet [{}] not exist!", this.sheetName); throw new POIException("Sheet [{}] not exist!", this.sheetName);
} }
if(this.curRid != -1 && isProcessCurrentSheet()) { if(this.curRid != -1 && isProcessCurrentSheet()) {
@ -369,35 +369,35 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
*/ */
private boolean isProcessCurrentSheet() { private boolean isProcessCurrentSheet() {
// rid < 0 sheet名称存在说明没有匹配到sheet名称 // rid < 0 sheet名称存在说明没有匹配到sheet名称
return (this.rid < 0 && null == this.sheetName) || this.rid == this.curRid; return (this.sheetIndex < 0 && null == this.sheetName) || this.sheetIndex == this.curRid;
} }
/** /**
* 获取sheet索引从0开始 * 获取sheet索引从0开始
* <ul> * <ul>
* <li>传入'rId'开头直接去除rId前缀</li> * <li>传入'rId'开头直接去除rId前缀</li>
* <li>传入纯数字表示sheetIndex直接转换为rid</li> * <li>传入纯数字表示sheetIndex直接使用</li>
* </ul> * </ul>
* *
* @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名称从0开始rid必须加rId前缀例如rId0如果为-1处理所有编号的sheet * @param sheetIndexOrSheetName Excel中的sheet 编号或sheet名称从0开始如果为-1处理所有编号的sheet
* @return sheet索引从0开始 * @return sheet索引从0开始
* @since 5.5.5 * @since 5.5.5
*/ */
private int getSheetIndex(String idOrRidOrSheetName) { private int getSheetIndex(String sheetIndexOrSheetName) {
Assert.notBlank(idOrRidOrSheetName, "id or rid or sheetName must be not blank!"); Assert.notBlank(sheetIndexOrSheetName, "id or rid or sheetName must be not blank!");
// rid直接处理 // rid直接处理
if (StrUtil.startWithIgnoreCase(idOrRidOrSheetName, RID_PREFIX)) { if (StrUtil.startWithIgnoreCase(sheetIndexOrSheetName, RID_PREFIX)) {
return Integer.parseInt(StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, RID_PREFIX)); return Integer.parseInt(StrUtil.removePrefixIgnoreCase(sheetIndexOrSheetName, RID_PREFIX));
} else if(StrUtil.startWithIgnoreCase(idOrRidOrSheetName, SHEET_NAME_PREFIX)){ } else if(StrUtil.startWithIgnoreCase(sheetIndexOrSheetName, SHEET_NAME_PREFIX)){
// since 5.7.10支持任意名称 // since 5.7.10支持任意名称
this.sheetName = StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, SHEET_NAME_PREFIX); this.sheetName = StrUtil.removePrefixIgnoreCase(sheetIndexOrSheetName, SHEET_NAME_PREFIX);
} else { } else {
try { try {
return Integer.parseInt(idOrRidOrSheetName); return Integer.parseInt(sheetIndexOrSheetName);
} catch (NumberFormatException ignore) { } catch (NumberFormatException ignore) {
// 如果用于传入非数字按照sheet名称对待 // 如果用于传入非数字按照sheet名称对待
this.sheetName = idOrRidOrSheetName; this.sheetName = sheetIndexOrSheetName;
} }
} }

View File

@ -14,11 +14,7 @@ import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.poi.xwpf.usermodel.XWPFRun;
import java.awt.*; import java.awt.*;
import java.io.Closeable; import java.io.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/** /**
* Word docx生成器 * Word docx生成器
@ -156,7 +152,8 @@ public class Word07Writer implements Closeable {
run.setItalic(font.isItalic()); run.setItalic(font.isItalic());
} }
if (null != color) { if (null != color) {
String hexColor = String.format("%02X", color.getRGB()); // setColor expects a pure RGB hex string (no alpha channel)
String hexColor = String.format("%06X", color.getRGB() & 0xFFFFFF);
run.setColor(hexColor); run.setColor(hexColor);
} }
} }

View File

@ -5,6 +5,8 @@ import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Console; import cn.hutool.core.lang.Console;
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.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -15,6 +17,8 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class WordWriterTest { public class WordWriterTest {
@Test @Test
@ -96,4 +100,17 @@ public class WordWriterTest {
word07Writer.addTable(list); word07Writer.addTable(list);
word07Writer.close(); word07Writer.close();
} }
@Test
public void addTextShouldStripAlphaAndUseRgbHex() {
final Word07Writer writer = new Word07Writer();
final Color colorWithAlpha = new Color(0x12, 0x34, 0x56, 0x7F);
writer.addText(new Font("宋体", Font.PLAIN, 12), colorWithAlpha, "带颜色的段落");
final XWPFParagraph paragraph = writer.getDoc().getParagraphArray(0);
final XWPFRun run = paragraph.getRuns().get(0);
assertEquals("123456", run.getColor());
writer.close();
}
} }