4

我正在使用 Apache POI 写入 Excel 文件,但我希望我的输出格式为 HTML 而不是文字文本。

SXSSFWorkbook workbook = new SXSSFWorkbook();
Sheet sheet0 = workbook.createSheet("sheet0");
Row row0 = sheet0.createRow(2);
Cell cell0 = row0.createCell(2);

cell0.setCellValue("<html><b>blah blah blah</b></html>");

打开 Excel 文件时出现的内容是:

"<html><b>blah blah blah</b></html>"

但我想要:

“等等等等等等”

基本上我正在寻找一段代码:

cell0.setCellFormat(CellFormat.HTML);

除了,那不存在。

这是有关此主题的一些信息

http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/ss/examples/html/ToHtml.java

我现在试试这个:

public void printPage() throws IOException {
    try {
        ensureOut();
        if (completeHTML) {
            out.format(
                    "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>%n");
            out.format("<html>%n");
            out.format("<head>%n");
            out.format("</head>%n");
            out.format("<body>%n");
        }

        print();

        if (completeHTML) {
            out.format("</body>%n");
            out.format("</html>%n");
        }
    } finally {
        if (out != null)
            out.close();
        if (output instanceof Closeable) {
            Closeable closeable = (Closeable) output;
            closeable.close();
        }
    }
}
4

1 回答 1

4

基于我的 DocX 版本,这里是 Hssf 的改编版本。与其他版本一样,您必须为各种 css 样式调试和扩展循环。

更新:我昨天忽略了你想要一个流式 XSSF 解决方案,所以我摆弄了一下,如果可以只使用 usermodel 类(不是真的,当涉及到字体颜色),而且我想知道为什么 SXSSF 没有在我发现之前不要使用我的任何字体设置,这是目前的设计(参见错误52484

import java.awt.Color;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.util.Enumeration;
import javax.swing.text.*;
import javax.swing.text.html.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

public class StyledTextXls {
    public static void main(String[] args) throws Exception {
        HTMLEditorKit kit = new HTMLEditorKit();
        HTMLDocument doc = (HTMLDocument)kit.createDefaultDocument();
        kit.insertHTML(doc, doc.getLength(), "<p>paragraph <b>1</b></p>", 0, 0, null);
        kit.insertHTML(doc, doc.getLength(), "<p>paragraph <span style=\"color:red\">2</span></p>", 0, 0, null);

        Workbook wb = new XSSFWorkbook();
//      Workbook wb = new HSSFWorkbook();
//      Workbook wb = new SXSSFWorkbook(100); // doesn't work yet - see Bug 52484
        Sheet sheet = wb.createSheet();
        Row row = sheet.createRow(0);
        Cell cell = row.createCell(0);

        StringBuffer sb = new StringBuffer();
        for (int lines=0, lastPos=-1; lastPos < doc.getLength(); lines++) {
            if (lines > 0) sb.append("\n");
            Element line = doc.getParagraphElement(lastPos+1);
            lastPos = line.getEndOffset();
            for (int elIdx=0; elIdx < line.getElementCount(); elIdx++) {
                final Element frag = line.getElement(elIdx);
                String subtext = doc.getText(frag.getStartOffset(), frag.getEndOffset()-frag.getStartOffset());
                sb.append(subtext);
            }           
        }

        CreationHelper ch = wb.getCreationHelper();
        RichTextString rt = ch.createRichTextString(sb.toString());
        for (int lines=0, lastPos=-1; lastPos < doc.getLength(); lines++) {
            Element line = doc.getParagraphElement(lastPos+1);
            lastPos = line.getEndOffset();
            for (int elIdx=0; elIdx < line.getElementCount(); elIdx++) {
                final Element frag = line.getElement(elIdx);
                Font font = getFontFromFragment(wb, frag);
                rt.applyFont(frag.getStartOffset()+lines, frag.getEndOffset()+lines, font);

            }           
        }       

        cell.setCellValue(rt);
        cell.getCellStyle().setWrapText(true);
        row.setHeightInPoints((6*sheet.getDefaultRowHeightInPoints()));
        sheet.autoSizeColumn((short)0);

        FileOutputStream fos = new FileOutputStream("richtext"+(wb instanceof HSSFWorkbook ? ".xls" : ".xlsx"));
        wb.write(fos);
        fos.close();
    }

    static Font getFontFromFragment(Workbook wb, Element frag) {
        // creating a font on each is call is not very efficient
        // but should be ok for this exercise ...
        Font font = wb.createFont();

        final AttributeSet as = frag.getAttributes();
        final Enumeration<?> ae = as.getAttributeNames();

        while (ae.hasMoreElements()) {
            final Object attrib = ae.nextElement();

            try {
                if (CSS.Attribute.COLOR.equals(attrib)) {
                    // I don't know how to really work with the CSS-swing class ...
                    Field f = as.getAttribute(attrib).getClass().getDeclaredField("c");
                    f.setAccessible(true);
                    Color c = (Color)f.get(as.getAttribute(attrib));
                    if (font instanceof XSSFFont) {
                        ((XSSFFont)font).setColor(new XSSFColor(c));
                    } else if (font instanceof HSSFFont && wb instanceof HSSFWorkbook) {
                        HSSFPalette pal = ((HSSFWorkbook)wb).getCustomPalette();
                        HSSFColor col = pal.findSimilarColor(c.getRed(), c.getGreen(), c.getBlue());
                        ((HSSFFont)font).setColor(col.getIndex());
                    }
                } else if (CSS.Attribute.FONT_WEIGHT.equals(attrib)) {
                    if ("bold".equals(as.getAttribute(attrib).toString())) {
                        font.setBoldweight(Font.BOLDWEIGHT_BOLD);
                    }
                }
            } catch (Exception e) {
                System.out.println(attrib.getClass().getCanonicalName()+" can't be handled.");
            }
        }               

        return font;
    }
}
于 2013-08-28T22:27:25.240 回答