1.问题:
poi默认只支持字符串页眉,不支持设置图片页眉
2.结论:
poi默认只支持字符串页眉设置,不支持图片设置页眉,从代码中也可以发现poi根本就不支持图片设置页眉,所以想直接通过扩展poi的默认写页眉方法来支持图片页眉的同学可以收手了, 已经给各位踩坑行不通.
3.代码详解
3.1 poi中拿到XSSFWorkbook设置页眉代码如下
XSSFWorkbook workbook = sheet.getWorkbook();
sheet.getHeader().setLeft("我是页眉");
3.2 可见setLeft具体方法只能设置字符串
public interface Header extends HeaderFooter {
String getLeft();
void setLeft(String var1);
String getCenter();
void setCenter(String var1);
String getRight();
void setRight(String var1);
}
public abstract class XSSFHeaderFooter implements HeaderFooter {
public void setLeft(String newLeft) {
this.setText(this.helper.setLeftSection(this.getText(), newLeft));
}
protected abstract void setText(String var1);
}
3.3 可见最终使用XSSFOddFooter.setText来实现页眉设置
public class XSSFOddFooter extends XSSFHeaderFooter implements Footer {
public void setText(String text) {
if (text == null) {
this.getHeaderFooter().unsetOddFooter();
} else {
this.getHeaderFooter().setOddFooter(text);
}
}
}
3.4 可见最终由SimpleValue.setStringValue(var1)实现写入
public class CTHeaderFooterImpl extends XmlComplexContentImpl implements CTHeaderFooter {
public void setOddFooter(String var1) {
synchronized(this.monitor()) {
this.check_orphaned();
SimpleValue var3 = null;
var3 = (SimpleValue)this.get_store().find_element_user(ODDFOOTER$2, 0);
if (var3 == null) {
var3 = (SimpleValue)this.get_store().add_element_user(ODDFOOTER$2);
}
var3.setStringValue(var1);
}
}
}
3.5 可见SimpleValue有setStringValue字符串实现写入也有setByteArrayValue直接byte流写入,不知道这个byte流底层是否已经支持,我们往下在找
public interface SimpleValue extends XmlObject {
void setStringValue(String var1);
void setBooleanValue(boolean var1);
void setByteValue(byte var1);
void setShortValue(short var1);
void setIntValue(int var1);
void setByteArrayValue(byte[] var1);
}
3.6 可见XmlObjectBase中set_String的实现以及set_ByteArray不支持而直接抛的exception.value.not.supported.j2s异常
public abstract class XmlObjectBase implements TypeStoreUser, Serializable, XmlObject, SimpleValue {
public void setStringValue(String obj) {
this.set(obj);
}
public final void set(String obj) {
if (obj == null) {
this.setNil();
} else {
synchronized(this.monitor()) {
this.set_prepare();
this.set_String(obj);
}
}
}
protected void set_String(String v) {
if ((this._flags & 4096) != 0) {
throw new IllegalStateException();
} else {
boolean wasNilled = (this._flags & 64) != 0;
String wscanon = this.apply_wscanon(v);
this.update_from_wscanon_text(wscanon);
if ((this._flags & 16) != 0) {
this._flags &= -33;
if ((this._flags & 1024) == 0) {
this.get_store().store_text(v);
}
if (wasNilled) {
this.get_store().invalidate_nil();
}
} else {
this._textsource = v;
}
}
}
public void setByteArrayValue(byte[] obj) {
this.set(obj);
}
public final void set(byte[] obj) {
if (obj == null) {
this.setNil();
} else {
synchronized(this.monitor()) {
this.set_prepare();
this.set_ByteArray(obj);
this.set_commit();
}
}
}
protected void set_ByteArray(byte[] b) {
throw new XmlValueNotSupportedException("exception.value.not.supported.j2s", new Object[]{"byte[]", this.getPrimitiveTypeName()});
}
}
虽然set_ByteArray使用protect方法修饰,存在可以继承XmlObjectBase,然后重写set_ByteArray的可能,但是看到set_String的复杂度以及各种魔法参数,已经劝退重写的可能性,所以至此可以断定poi原本是不支持图片作为页眉的.