使用POI将HTML Table导出Excel

December 17, 2023
测试
测试
测试
测试
46 分钟阅读

将页面复杂的Table导出为Excel文档

一、POI依赖

       <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.8</version>
        </dependency>

二、导出工具类

1、使用HSSFWorkbook

package com.demo.utils;
 
import com.demo.model.CrossRangeCellMeta;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
 
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
 
 
/**
 * 类名:Html2Excel.java
 * 路径:com.demo.utils.Html2Excel.java
 * 创建人:tanyp
 * 创建时间:2019/9/19 10:00
 * 功能:将html table转成excel
 * 修改人:
 * 修改时间:
 * 修改备注:
 */
public class Html2Excel {
 
    /**
     * 方法名:table2Excel
     * 功能:html表格转excel
     * 创建人:tanyp
     * 创建时间:2019/9/19 10:00
     * 入参:html字符串:<table> ... </table>
     * 出参:excel
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    public static HSSFWorkbook table2Excel(String tableHtml) {
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet();
        HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        List<CrossRangeCellMeta> crossRowEleMetaLs = new ArrayList<>();
        int rowIndex = 0;
        try {
            Document data = DocumentHelper.parseText(tableHtml);
            // 生成表头
            Element thead = data.getRootElement().element("thead");
            HSSFCellStyle titleStyle = getTitleStyle(wb);
            if (thead != null) {
                List<Element> trLs = thead.elements("tr");
                for (Element trEle : trLs) {
                    HSSFRow row = sheet.createRow(rowIndex);
                    List<Element> thLs = trEle.elements("th");
                    makeRowCell(thLs, rowIndex, row, 0, titleStyle, crossRowEleMetaLs);
                    row.setHeightInPoints(17);
                    rowIndex++;
                }
            }
            // 生成表体
            Element tbody = data.getRootElement().element("tbody");
            if (tbody != null) {
                HSSFCellStyle contentStyle = getContentStyle(wb);
                List<Element> trLs = tbody.elements("tr");
                for (Element trEle : trLs) {
                    HSSFRow row = sheet.createRow(rowIndex);
                    List<Element> thLs = trEle.elements("th");
                    int cellIndex = makeRowCell(thLs, rowIndex, row, 0, titleStyle, crossRowEleMetaLs);
                    List<Element> tdLs = trEle.elements("td");
                    makeRowCell(tdLs, rowIndex, row, cellIndex, contentStyle, crossRowEleMetaLs);
                    row.setHeightInPoints(18);
                    rowIndex++;
                }
            }
            // 合并表头
            for (CrossRangeCellMeta crcm : crossRowEleMetaLs) {
                sheet.addMergedRegion(new CellRangeAddress(crcm.getFirstRow(), crcm.getLastRow(), crcm.getFirstCol(), crcm.getLastCol()));
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //自动调整列宽
        for (int i = 0; i < 15; i++) {
            sheet.autoSizeColumn((short) i);
        }
        return wb;
    }
 
    /**
     * 方法名:makeRowCell
     * 功能:生产行内容
     * 创建人:tanyp
     * 创建时间:2019/9/19 10:01
     * 入参:
     * tdLs: th或者td集合;
     * rowIndex: 行号;
     * row: POI行对象;
     * startCellIndex;
     * cellStyle: 样式;
     * crossRowEleMetaLs:跨行元数据集合
     * 出参:
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    private static int makeRowCell(List<Element> tdLs, int rowIndex, HSSFRow row, int startCellIndex, HSSFCellStyle cellStyle, List<CrossRangeCellMeta> crossRowEleMetaLs) {
        int i = startCellIndex;
        for (int eleIndex = 0; eleIndex < tdLs.size(); i++, eleIndex++) {
            int captureCellSize = getCaptureCellSize(rowIndex, i, crossRowEleMetaLs);
            while (captureCellSize > 0) {
                // 当前行跨列处理(补单元格)
                for (int j = 0; j < captureCellSize; j++) {
                    row.createCell(i);
                    i++;
                }
                captureCellSize = getCaptureCellSize(rowIndex, i, crossRowEleMetaLs);
            }
            Element thEle = tdLs.get(eleIndex);
            String val = thEle.getTextTrim();
            if (StringUtils.isBlank(val)) {
                Element e = thEle.element("a");
                if (e != null) {
                    val = e.getTextTrim();
                }
            }
            HSSFCell c = row.createCell(i);
            if (NumberUtils.isNumber(val)) {
                c.setCellValue(Double.parseDouble(val));
                c.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
            } else {
                c.setCellValue(val);
            }
            c.setCellStyle(cellStyle);
            int rowSpan = NumberUtils.toInt(thEle.attributeValue("rowspan"), 1);
            int colSpan = NumberUtils.toInt(thEle.attributeValue("colspan"), 1);
            // 存在跨行或跨列
            if (rowSpan > 1 || colSpan > 1) {
                crossRowEleMetaLs.add(new CrossRangeCellMeta(rowIndex, i, rowSpan, colSpan));
            }
            // 当前行跨列处理(补单元格)
            if (colSpan > 1) {
                for (int j = 1; j < colSpan; j++) {
                    i++;
                    row.createCell(i);
                }
            }
        }
        return i;
    }
 
    /**
     * 方法名:getCaptureCellSize
     * 功能:获得因rowSpan占据的单元格
     * 创建人:tanyp
     * 创建时间:2019/9/19 10:03
     * 入参:
     * rowIndex:行号
     * colIndex:列号
     * crossRowEleMetaLs:跨行列元数据
     * 出参:当前行在某列需要占据单元格
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    private static int getCaptureCellSize(int rowIndex, int colIndex, List<CrossRangeCellMeta> crossRowEleMetaLs) {
        int captureCellSize = 0;
        for (CrossRangeCellMeta crossRangeCellMeta : crossRowEleMetaLs) {
            if (crossRangeCellMeta.getFirstRow() < rowIndex && crossRangeCellMeta.getLastRow() >= rowIndex) {
                if (crossRangeCellMeta.getFirstCol() <= colIndex && crossRangeCellMeta.getLastCol() >= colIndex) {
                    captureCellSize = crossRangeCellMeta.getLastCol() - colIndex + 1;
                }
            }
        }
        return captureCellSize;
    }
 
    /**
     * 方法名:getTitleStyle
     * 功能:获得标题样式
     * 创建人:tanyp
     * 创建时间:2019/9/19 10:04
     * 入参:workbook
     * 出参:
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    private static HSSFCellStyle getTitleStyle(HSSFWorkbook workbook) {
        short titlebackgroundcolor = HSSFColor.GREY_25_PERCENT.index;
        short fontSize = 12;
        String fontName = "宋体";
        HSSFCellStyle style = workbook.createCellStyle();
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        style.setBorderBottom((short) 1);
        style.setBorderTop((short) 1);
        style.setBorderLeft((short) 1);
        style.setBorderRight((short) 1);
        style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        // 背景色
        style.setFillForegroundColor(titlebackgroundcolor);
        HSSFFont font = workbook.createFont();
        font.setFontName(fontName);
        font.setFontHeightInPoints(fontSize);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        style.setFont(font);
        return style;
    }
 
    /**
     * 方法名:getContentStyle
     * 功能:获得内容样式
     * 创建人:tanyp
     * 创建时间:2019/9/19 10:05
     * 入参:HSSFWorkbook
     * 出参:
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    private static HSSFCellStyle getContentStyle(HSSFWorkbook wb) {
        short fontSize = 12;
        String fontName = "宋体";
        HSSFCellStyle style = wb.createCellStyle();
        style.setBorderBottom((short) 1);
        style.setBorderTop((short) 1);
        style.setBorderLeft((short) 1);
        style.setBorderRight((short) 1);
        HSSFFont font = wb.createFont();
        font.setFontName(fontName);
        font.setFontHeightInPoints(fontSize);
        style.setFont(font);
        return style;
    }
 
}

异常:使用Html2Excel.java导出时列超过256时会报错:

Invalid column index (256). Allowable column range for BIFF8 is (0..255) or ('A'..'IV')。

原因:使用HSSFWorkbook最多只能创建256列,超过就会报上述的错误。

解决方法:使用XSSFWorkbook创建,最多可以创建16384列。修改Html2Excel工具类为XHtml2Excel.java,如下:

2、使用XSSFWorkbook

package com.demo.utils;
 
import com.demo.model.CrossRangeCellMeta;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
 
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
 
 
/**
 * 类名:XHtml2Excel.java
 * 路径:com.demo.utils.XHtml2Excel.java
 * 创建人:tanyp
 * 创建时间:2019/9/19 10:00
 * 功能:将html table转成excel
 * 修改人:
 * 修改时间:
 * 修改备注:
 */
public class XHtml2Excel {
 
    /**
     * 方法名:table2Excel
     * 功能:html表格转excel
     * 创建人:tanyp
     * 创建时间:2019/9/19 10:00
     * 入参:html字符串:<table> ... </table>
     * 出参:excel
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    public static XSSFWorkbook table2Excel(String tableHtml) {
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet();
        XSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        List<CrossRangeCellMeta> crossRowEleMetaLs = new ArrayList<>();
        int rowIndex = 0;
        try {
            Document data = DocumentHelper.parseText(tableHtml);
            // 生成表头
            Element thead = data.getRootElement().element("thead");
            XSSFCellStyle titleStyle = getTitleStyle(wb);
            if (thead != null) {
                List<Element> trLs = thead.elements("tr");
                for (Element trEle : trLs) {
                    XSSFRow row = sheet.createRow(rowIndex);
                    List<Element> thLs = trEle.elements("th");
                    makeRowCell(thLs, rowIndex, row, 0, titleStyle, crossRowEleMetaLs);
                    row.setHeightInPoints(17);
                    rowIndex++;
                }
            }
            // 生成表体
            Element tbody = data.getRootElement().element("tbody");
            if (tbody != null) {
                XSSFCellStyle contentStyle = getContentStyle(wb);
                List<Element> trLs = tbody.elements("tr");
                for (Element trEle : trLs) {
                    XSSFRow row = sheet.createRow(rowIndex);
                    List<Element> thLs = trEle.elements("th");
                    int cellIndex = makeRowCell(thLs, rowIndex, row, 0, titleStyle, crossRowEleMetaLs);
                    List<Element> tdLs = trEle.elements("td");
                    makeRowCell(tdLs, rowIndex, row, cellIndex, contentStyle, crossRowEleMetaLs);
                    row.setHeightInPoints(18);
                    rowIndex++;
                }
            }
            // 合并表头
            for (CrossRangeCellMeta crcm : crossRowEleMetaLs) {
                sheet.addMergedRegion(new CellRangeAddress(crcm.getFirstRow(), crcm.getLastRow(), crcm.getFirstCol(), crcm.getLastCol()));
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //自动调整列宽
        for (int i = 0; i < 15; i++) {
            sheet.autoSizeColumn((short) i);
        }
        return wb;
    }
 
    /**
     * 方法名:makeRowCell
     * 功能:生产行内容
     * 创建人:tanyp
     * 创建时间:2019/9/19 10:01
     * 入参:
     * tdLs: th或者td集合;
     * rowIndex: 行号;
     * row: POI行对象;
     * startCellIndex;
     * cellStyle: 样式;
     * crossRowEleMetaLs:跨行元数据集合
     * 出参:
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    private static int makeRowCell(List<Element> tdLs, int rowIndex, XSSFRow row, int startCellIndex, XSSFCellStyle cellStyle, List<CrossRangeCellMeta> crossRowEleMetaLs) {
        int i = startCellIndex;
        for (int eleIndex = 0; eleIndex < tdLs.size(); i++, eleIndex++) {
            int captureCellSize = getCaptureCellSize(rowIndex, i, crossRowEleMetaLs);
            while (captureCellSize > 0) {
                // 当前行跨列处理(补单元格)
                for (int j = 0; j < captureCellSize; j++) {
                    row.createCell(i);
                    i++;
                }
                captureCellSize = getCaptureCellSize(rowIndex, i, crossRowEleMetaLs);
            }
            Element thEle = tdLs.get(eleIndex);
            String val = thEle.getTextTrim();
            if (StringUtils.isBlank(val)) {
                Element e = thEle.element("a");
                if (e != null) {
                    val = e.getTextTrim();
                }
            }
            XSSFCell c = row.createCell(i);
            if (NumberUtils.isNumber(val)) {
                c.setCellValue(Double.parseDouble(val));
                c.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
            } else {
                c.setCellValue(val);
            }
            c.setCellStyle(cellStyle);
            int rowSpan = NumberUtils.toInt(thEle.attributeValue("rowspan"), 1);
            int colSpan = NumberUtils.toInt(thEle.attributeValue("colspan"), 1);
            // 存在跨行或跨列
            if (rowSpan > 1 || colSpan > 1) {
                crossRowEleMetaLs.add(new CrossRangeCellMeta(rowIndex, i, rowSpan, colSpan));
            }
            // 当前行跨列处理(补单元格)
            if (colSpan > 1) {
                for (int j = 1; j < colSpan; j++) {
                    i++;
                    row.createCell(i);
                }
            }
        }
        return i;
    }
 
    /**
     * 方法名:getCaptureCellSize
     * 功能:获得因rowSpan占据的单元格
     * 创建人:tanyp
     * 创建时间:2019/9/19 10:03
     * 入参:
     * rowIndex:行号
     * colIndex:列号
     * crossRowEleMetaLs:跨行列元数据
     * 出参:当前行在某列需要占据单元格
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    private static int getCaptureCellSize(int rowIndex, int colIndex, List<CrossRangeCellMeta> crossRowEleMetaLs) {
        int captureCellSize = 0;
        for (CrossRangeCellMeta crossRangeCellMeta : crossRowEleMetaLs) {
            if (crossRangeCellMeta.getFirstRow() < rowIndex && crossRangeCellMeta.getLastRow() >= rowIndex) {
                if (crossRangeCellMeta.getFirstCol() <= colIndex && crossRangeCellMeta.getLastCol() >= colIndex) {
                    captureCellSize = crossRangeCellMeta.getLastCol() - colIndex + 1;
                }
            }
        }
        return captureCellSize;
    }
 
    /**
     * 方法名:getTitleStyle
     * 功能:获得标题样式
     * 创建人:tanyp
     * 创建时间:2019/9/19 10:04
     * 入参:workbook
     * 出参:
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    private static XSSFCellStyle getTitleStyle(XSSFWorkbook workbook) {
        short titlebackgroundcolor = HSSFColor.GREY_25_PERCENT.index;
        short fontSize = 12;
        String fontName = "宋体";
        XSSFCellStyle style = workbook.createCellStyle();
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        style.setBorderBottom((short) 1);
        style.setBorderTop((short) 1);
        style.setBorderLeft((short) 1);
        style.setBorderRight((short) 1);
        style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        // 背景色
        style.setFillForegroundColor(titlebackgroundcolor);
        XSSFFont font = workbook.createFont();
        font.setFontName(fontName);
        font.setFontHeightInPoints(fontSize);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        style.setFont(font);
        return style;
    }
 
    /**
     * 方法名:getContentStyle
     * 功能:获得内容样式
     * 创建人:tanyp
     * 创建时间:2019/9/19 10:05
     * 入参:HSSFWorkbook
     * 出参:
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    private static XSSFCellStyle getContentStyle(XSSFWorkbook wb) {
        short fontSize = 12;
        String fontName = "宋体";
        XSSFCellStyle style = wb.createCellStyle();
        style.setBorderBottom((short) 1);
        style.setBorderTop((short) 1);
        style.setBorderLeft((short) 1);
        style.setBorderRight((short) 1);
        XSSFFont font = wb.createFont();
        font.setFontName(fontName);
        font.setFontHeightInPoints(fontSize);
        style.setFont(font);
        return style;
    }
 
}

3、跨行列实体类

package com.demo.model;
 
/**
 * 类名:CrossRangeCellMeta.java
 * 路径:com.winner.model.CrossRangeCellMeta.java
 * 创建人:tanyp
 * 创建时间:2019/9/19 10:00
 * 功能:跨行元素元数据
 * 修改人:
 * 修改时间:
 * 修改备注:
 */
public class CrossRangeCellMeta {
 
    public CrossRangeCellMeta(int firstRowIndex, int firstColIndex, int rowSpan, int colSpan) {
        super();
        this.firstRowIndex = firstRowIndex;
        this.firstColIndex = firstColIndex;
        this.rowSpan = rowSpan;
        this.colSpan = colSpan;
    }
 
    private int firstRowIndex;
    private int firstColIndex;
    // 跨越行数
    private int rowSpan;
    // 跨越列数
    private int colSpan;
 
    public int getFirstRow() {
        return firstRowIndex;
    }
 
    public int getLastRow() {
        return firstRowIndex + rowSpan - 1;
    }
 
    public int getFirstCol() {
        return firstColIndex;
    }
 
    public int getLastCol() {
        return firstColIndex + colSpan - 1;
    }
 
    public int getColSpan() {
        return colSpan;
    }
}

4、controller调用

/**
 * 类名:Html2ExcelController.java
 * 路径:com.demo.controller.Html2ExcelController.java
 * 创建人:tanyp
 * 创建时间:2019/9/19 10:00
 * 功能:HTML table导出excel
 * 修改人:
 * 修改时间:
 * 修改备注:
 */
@Controller
public class Html2ExcelController {
     private static final Logger log = LoggerFactory.getLogger(Html2ExcelController.class);
 
   /**
     * 方法名:exportExcel
     * 功能:导出
     * 创建人:tanyp
     * 创建时间:2019/9/19 11:07
     * 入参:dataTable
     * 出参:
     * 修改人:
     * 修改时间:
     * 修改备注:
     */
    @RequestMapping("exportExcel")
    public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
        try {
            String dataTable = request.getParameter("dataTable");
            String fileName = "测试"+System.currentTimeMillis()+".xls";
            // 各浏览器基本都支持ISO编码
            String userAgent = request.getHeader("User-Agent").toUpperCase();
            if (userAgent.contains("TRIDENT") || userAgent.contains("EDGE")) {
                fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            } else if (userAgent.contains("MSIE")) {
                fileName = new String(fileName.getBytes(), "ISO-8859-1");
            } else {
                fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
            }
 
            response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", fileName));
            OutputStream os = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/vnd.ms-excel;charset=gb2312");
            //将excel写入到输出流中
            HSSFWorkbook workbook = Html2Excel.table2Excel(dataTable);
            // XSSFWorkbook workbook = XHtml2Excel.table2Excel(dataTable);
            workbook.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("请求 exportExcel异常:{}", e.getMessage());
        }
    }
}

备注:

使用两个不同工具类时导包不同(HSSFWorkbook或XSSFWorkbook) 。

5、HTML代码

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script type="text/javascript" src="js/jquery.js"></script>
</head>
<body>
<div onclick="download()">导出</div>
<div id="DateTable" style="overflow-x:scroll">
<table id="myTable" class="gridtable w2000"><thead><tr><th rowspan="2" style="min-width: 100px; max-width: 100px;width: 100px;">名称</th><th rowspan="2" style="min-width: 80px; max-width: 80px;width: 80px;">客流总量(人次)</th><th rowspan="2" style="min-width: 80px; max-width: 80px;width: 80px;">编码</th><th rowspan="2" style="min-width: 80px; max-width: 80px;width: 80px;">单客流总量(人次)</th><th colspan="3">时段客流(人次)</th></tr><tr><th style="min-width: 80px; max-width: 80px;width: 80px;">01:05</th><th style="min-width: 80px; max-width: 80px;width: 80px;">01:10</th><th style="min-width: 80px; max-width: 80px;width: 80px;">01:15</th></tr></thead><tbody id="pointBasedDateTbody"><tr><td rowspan="2">购物一号门</td><td rowspan="2">5006</td><td>C001</td><td>3006</td><td>0</td><td>0</td><td>0</td></tr><tr><td>C002</td><td>2000</td><td>0</td><td>0</td><td>0</td></tr><tr><td rowspan="2">购物二号门</td><td rowspan="2">2796</td><td>C001</td><td>1542</td><td>0</td><td>0</td><td>0</td></tr><tr><td>C002</td><td>1254</td><td>0</td><td>0</td><td>0</td></tr><tr><td rowspan="1">购物三号门</td><td rowspan="1">1654</td><td>C005</td><td>1654</td><td>0</td><td>0</td><td>0</td></tr><tr><td rowspan="1">购物四号门</td><td rowspan="1">54365</td><td>C001</td><td>54365</td><td>0</td><td>0</td><td>0</td></tr></tbody></table>
</div>
<form action="exportExcel" id="exportExcle" method="POST">
        <input type="hidden" name="dataTable" id="dataTable">
</form>
</body>
<script>
function download() {
    var html = $("#tables").html();
    $("#dataTable").val(html);
    $("#exportExcle").submit();
};
</script>
</html>

6、效果图

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多