poi源码详解默认只支持字符串页眉原因

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原本是不支持图片作为页眉的.

你可能感兴趣的:(Excel处理,Java基础,java,c#,android)