Jxls表格导出功能帮助文档

  • 业务介绍
    • 功能实现

业务介绍

做一个时刻表的导出功能,数据模型都已经写好了。原型图大概是这样的一个意思。先看图:

大概设计是这个样子。
然后最后导出的成品是这个样子:

大概业务明确之后,我就开始进行实现了。

功能实现

我是参照了一个开源后台管理项目中的模板导出功能扒下来的,有兴趣的同学们可以去看看人家的代码。我觉得还可以,附带项目代码链接:链接: http://webflash.enilu.cn/.

  1. 依赖的jar:这个一定要注意版本号,我在这上面排坑拍了一上午,实际代码都没问题,但是在导出的时候会被各种异常困扰。后来总结复盘了一下就是因为版本号的问题导致的。下面展示一些
    dependency
     <dependency><groupId>org.jxls</groupId><artifactId>jxls</artifactId><version>2.3.0</version></dependency><dependency><groupId>org.jxls</groupId><artifactId>jxls-poi</artifactId><version>1.0.9</version></dependency><!--数据导出excel--><!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.8</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.8</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>3.8</version></dependency>

这个是我调查了很多帖子找到的能用的一个。有

poi
poi-ooxml
poi-ooxml-schemas

这三个依赖一定要3.8的我当时就不信邪,头铁各种debug到源码了发现根本行。都没那个模板导出的语法规则。
2. 一些有用的until。我这里用到了一些Until,我觉得也不错都写在这里吧 。
XlsUtils:这个是为了表格上面进行格式化的,Jxls的句法跟JSTL的语法感觉很类似

/**
* @author wang hongyu
* @package_name signalsys-parent
* @date 2021/6/10
*/
public class XlsUtils {public String dateFmt(Date date, String fmt) {if (date == null) {return "";}return DateUtil.formatDate(date,fmt);}/*** 时间转换* @param time* @return*/public String handleTimeStr(Integer time) {if (time==null){time=0;}String timeStr=String.valueOf(time);String timer= "";if (timeStr.length()==6){String hour=timeStr.substring(0,2);String min =timeStr.substring(2,4);String sec =timeStr.substring(4);timer=hour+":"+min+":"+sec;}else if (timeStr.length()==5){String hour=timeStr.substring(0,1);String min =timeStr.substring(1,3);String sec =timeStr.substring(3);timer=hour+":"+min+":"+sec;}else{timer=timeStr;}return timer;}public String handleRate(String late){return late+"%";}public String handleTrainPlanCode(String scheduleCode,String trainPlanCode){return scheduleCode+trainPlanCode;}public String handleLate(Integer late){if (late!=null){if (late != 0) {int hour = late / (60 * 60);int min = (late - (hour * 60 * 60)) / 60;int sec = (late - (hour * 60 * 60) - (min * 60)) % (60 * 60);if (hour < 0) {return "+" + Math.abs(hour) + ":" + Math.abs(min) + ":" + Math.abs(sec);} else if (hour>0) {return "-" + Math.abs(hour) + ":" + Math.abs(min) + ":" + Math.abs(sec);}else{return  Math.abs(hour) + ":" + Math.abs(min) + ":" + Math.abs(sec);}}}return "";}
}

StringUtil:字符串处理相关

public class StringUtil {public static final String EMPTY = "";private static final AtomicLong ORDER_SEQ = new AtomicLong(1);private static  final Pattern PATERN_IP = Pattern.compile("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");/*** 是否为空字符*/public static boolean isEmpty(String str) {if (str == null || str.trim().length() == 0) {return true;}if ("null".equalsIgnoreCase(str) || "undefined".equalsIgnoreCase(str)) {return true;}return false;}/*** 是否为非空字符*/public static boolean isNotEmpty(String str) {return (!isEmpty(str));}/*** 判断是否为null或空字符*/public static boolean isNullOrEmpty(Object o) {if (o == null) {return true;}if (String.valueOf(o).replace((char) 12288, ' ').trim().length() == 0) {return true;}if ("null".equals(o)) {return true;}return false;}/*** 判断是否不为null或非空字符*/public static boolean isNotNullOrEmpty(Object o) {return !isNullOrEmpty(o);}// 根据Unicode编码完美的判断中文汉字和符号private static boolean isChinese(char c) {Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {return true;}return false;}public static String sNull(Object obj) {return obj==null?"":obj.toString();}/*** 格式化文本,使用 {varName} 占位<br>* map = {a: "aValue", b: "bValue"}* format("{a} and {b}", map)    ---->    aValue and bValue** @param template 文本模板,被替换的部分用 {key} 表示* @param map 参数值对* @return 格式化后的文本*/public static String format(String template, Map<?, ?> map) {if (null == map || map.isEmpty()) {return template;}for (Map.Entry<?, ?> entry : map.entrySet()) {template = template.replace("{" + entry.getKey() + "}", entry.getValue().toString());}return template;}/*** 改进JDK subString<br>* index从0开始计算,最后一个字符为-1<br>* 如果from和to位置一样,返回 "" <br>* 如果from或to为负数,则按照length从后向前数位置,如果绝对值大于字符串长度,则from归到0,to归到length<br>* 如果经过修正的index中from大于to,则互换from和to* example: <br>*   abcdefgh 2 3 -> c <br>*    abcdefgh 2 -3 -> cde <br>** @param string String* @param fromIndex 开始的index(包括)* @param toIndex 结束的index(不包括)* @return 字串*/public static String sub(String string, int fromIndex, int toIndex) {int len = string.length();if (fromIndex < 0) {fromIndex = len + fromIndex;if(fromIndex < 0 ) {fromIndex = 0;}} else if(fromIndex >= len) {fromIndex = len -1;}if (toIndex < 0) {toIndex = len + toIndex;if(toIndex < 0) {toIndex = len;}} else if(toIndex > len) {toIndex = len;}if (toIndex < fromIndex) {int tmp = fromIndex;fromIndex = toIndex;toIndex = tmp;}if (fromIndex == toIndex) {return EMPTY;}char[] strArray = string.toCharArray();char[] newStrArray = Arrays.copyOfRange(strArray, fromIndex, toIndex);return new String(newStrArray);}/*** 首字母变小写*/public static String firstCharToLowerCase(String str) {char firstChar = str.charAt(0);if (firstChar >= 'A' && firstChar <= 'Z') {char[] arr = str.toCharArray();arr[0] += ('a' - 'A');return new String(arr);}return str;}/*** 首字母变大写*/public static String firstCharToUpperCase(String str) {char firstChar = str.charAt(0);if (firstChar >= 'a' && firstChar <= 'z') {char[] arr = str.toCharArray();arr[0] -= ('a' - 'A');return new String(arr);}return str;}/*** 去掉指定前缀** @param str 字符串* @param prefix 前缀* @return 切掉后的字符串,若前缀不是 preffix, 返回原字符串*/public static String removePrefix(String str, String prefix) {if(isEmpty(str) || isEmpty(prefix)){return str;}if (str.startsWith(prefix)) {return str.substring(prefix.length());}return str;}/*** 去掉指定后缀** @param str 字符串* @param suffix 后缀* @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串*/public static String removeSuffix(String str, String suffix) {if(isEmpty(str) || isEmpty(suffix)){return str;}if (str.endsWith(suffix)) {return str.substring(0, str.length() - suffix.length());}return str;}/*** 获得字符串对应byte数组* @param str 字符串* @param charset 编码,如果为<code>null</code>使用系统默认编码* @return bytes*/public static byte[] getBytes(String str, Charset charset){if(null == str){return null;}return null == charset ? str.getBytes() : str.getBytes(charset);}/*** 切分字符串<br>* from jodd** @param str 被切分的字符串* @param delimiter 分隔符* @return 字符串*/public static String[] split(String str, String delimiter) {if (str == null) {return null;}if (str.trim().length() == 0) {return new String[] { str };}int dellen = delimiter.length(); // del lengthint maxparts = (str.length() / dellen) + 2; // one more for the lastint[] positions = new int[maxparts];int i, j = 0;int count = 0;positions[0] = -dellen;while ((i = str.indexOf(delimiter, j)) != -1) {count++;positions[count] = i;j = i + dellen;}count++;positions[count] = str.length();String[] result = new String[count];for (i = 0; i < count; i++) {result[i] = str.substring(positions[i] + dellen, positions[i + 1]);}return result;}/*** 比较两个字符串(大小写敏感)。** <pre>* equals(null, null)   = true* equals(null, &quot;abc&quot;)  = false* equals(&quot;abc&quot;, null)  = false* equals(&quot;abc&quot;, &quot;abc&quot;) = true* equals(&quot;abc&quot;, &quot;ABC&quot;) = false* </pre>** @param str1 要比较的字符串1* @param str2 要比较的字符串2** @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>*/public static boolean equals(String str1, String str2) {if (str1 == null) {return str2 == null;}return str1.equals(str2);}/*** 编码字符串** @param str 字符串* @param charset 字符集,如果此字段为空,则解码的结果取决于平台* @return 编码后的字节码*/public static byte[] bytes(String str, Charset charset) {if (str == null) {return null;}if (null == charset) {return str.getBytes();}return str.getBytes(charset);}/*** 解码字节码** @param data 字符串* @param charset 字符集,如果此字段为空,则解码的结果取决于平台* @return 解码后的字符串*/public static String str(byte[] data, Charset charset) {if (data == null) {return null;}if (null == charset) {return new String(data);}return new String(data, charset);}
}

DateUtil:日期工具类

/**
* @author wang hongyu
* @package_name signalsys-parent
* @date 2021/6/10
*/
public class DateUtil {private static final Object LOCK = new Object();private static final Map<String, ThreadLocal<SimpleDateFormat>> POOL = new HashMap<String, ThreadLocal<SimpleDateFormat>>();/*** 获取YYYY格式** @return*/public static String getYear() {return formatDate(new Date(), "yyyy");}/*** 获取YYYY格式** @return*/public static String getYear(Date date) {return formatDate(date, "yyyy");}/*** 获取YYYY-MM-DD格式** @return*/public static String getDay() {return formatDate(new Date(), "yyyy-MM-dd");}/*** 获取YYYY-MM-DD格式** @return*/public static String getDay(Date date) {return formatDate(date, "yyyy-MM-dd");}/*** 获取YYYYMMDD格式** @return*/public static String getDays() {return formatDate(new Date(), "yyyyMMdd");}/*** 获取YYYYMMDD格式** @return*/public static String getDays(Date date) {return formatDate(date, "yyyyMMdd");}/*** 获取YYYY-MM-DD HH:mm:ss格式** @return*/public static String getTime() {return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");}/*** 获取YYYY-MM-DD HH:mm:ss.SSS格式** @return*/public static String getMsTime() {return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");}/*** 获取YYYYMMDDHHmmss格式** @return*/public static String getAllTime() {return formatDate(new Date(), "yyyyMMddHHmmss");}/*** 获取YYYY-MM-DD HH:mm:ss格式** @return*/public static String getTime(Date date) {return formatDate(date, "yyyy-MM-dd HH:mm:ss");}public static String formatDate(Date date, String pattern) {String formatDate = null;if (StringUtil.isNotEmpty(pattern)) {formatDate = DateFormatUtils.format(date, pattern);} else {formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");}return formatDate;}/*** @Title: compareDate* @Description:(日期比较,如果s>=e 返回true 否则返回false)* @param s* @param e* @return boolean* @throws* @author luguosui*/public static boolean compareDate(String s, String e) {if (parseDate(s) == null || parseDate(e) == null) {return false;}return parseDate(s).getTime() >= parseDate(e).getTime();}/*** 格式化日期** @return*/public static Date parseDate(String date) {return parse(date,"yyyy-MM-dd");}/*** 格式化日期** @return*/public static Date parseTime(String date) {return parse(date,"yyyy-MM-dd HH:mm:ss");}/*** 格式化日期** @return*/public static Date parse(String date, String pattern) {if (date != null) {if (pattern == null || "".equals(pattern)) {return null;}DateFormat format = getDFormat(pattern);try {return format.parse(date);} catch (ParseException e) {e.printStackTrace();}}return null;}public static SimpleDateFormat getDFormat(String pattern) {ThreadLocal<SimpleDateFormat> tl = POOL.get(pattern);if (tl == null) {synchronized (LOCK) {tl = POOL.get(pattern);if (tl == null) {final String p = pattern;tl = new ThreadLocal<SimpleDateFormat>() {@Overrideprotected synchronized SimpleDateFormat initialValue() {return new SimpleDateFormat(p);}};POOL.put(p, tl);}}}return tl.get();}/*** 格式化日期** @return*/public static String format(Date date, String pattern) {return DateFormatUtils.format(date, pattern);}/*** 把日期转换为Timestamp** @param date* @return*/public static Timestamp format(Date date) {return new Timestamp(date.getTime());}/*** 校验日期是否合法** @return*/public static boolean isValidDate(String s) {return parse(s, "yyyy-MM-dd HH:mm:ss") != null;}/*** 校验日期是否合法** @return*/public static boolean isValidDate(String s, String pattern) {return parse(s, pattern) != null;}public static int getDiffYear(String startTime, String endTime) {DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");try {int years = (int) (((fmt.parse(endTime).getTime() - fmt.parse(startTime).getTime()) / (1000 * 60 * 60 * 24)) / 365);return years;} catch (Exception e) {// 如果throw java.text.ParseException或者NullPointerException,就说明格式不对return 0;}}/*** <li>功能描述:时间相减得到天数** @param beginDateStr* @param endDateStr* @return long* @author Administrator*/public static long getDaySub(String beginDateStr, String endDateStr) {long day = 0;SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");Date beginDate = null;Date endDate = null;try {beginDate = format.parse(beginDateStr);endDate = format.parse(endDateStr);} catch (ParseException e) {e.printStackTrace();}day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);// System.out.println("相隔的天数="+day);return day;}/*** 得到n天之后的日期** @param days* @return*/public static String getAfterDayDate(String days) {int daysInt = Integer.parseInt(days);Calendar canlendar = Calendar.getInstance(); // java.util包canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动Date date = canlendar.getTime();SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String dateStr = sdfd.format(date);return dateStr;}/*** 得到n天之后是周几** @param days* @return*/public static String getAfterDayWeek(String days) {int daysInt = Integer.parseInt(days);Calendar canlendar = Calendar.getInstance(); // java.util包canlendar.add(Calendar.DATE, daysInt); // 日期减 如果不够减会将月变动Date date = canlendar.getTime();SimpleDateFormat sdf = new SimpleDateFormat("E");String dateStr = sdf.format(date);return dateStr;}public static Date asDate(LocalDateTime localDateTime) {return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());}public static LocalDateTime asLocalDateTime(Date date) {return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();}/*** 获取今天* @return String* */public static String getToday(){return new SimpleDateFormat("yyyy-MM-dd").format(new Date());}/*** 获取昨天* @return String* */public static String getYestoday(){Calendar cal=Calendar.getInstance();cal.add(Calendar.DATE,-1);Date time=cal.getTime();return new SimpleDateFormat("yyyy-MM-dd").format(time);}/*** 获取本月开始日期* @return String* **/public static String getMonthStart(){Calendar cal=Calendar.getInstance();cal.add(Calendar.MONTH, 0);cal.set(Calendar.DAY_OF_MONTH, 1);Date time=cal.getTime();return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 00:00:00";}/*** 获取本月最后一天* @return String* **/public static String getMonthEnd(){Calendar cal=Calendar.getInstance();cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));Date time=cal.getTime();return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 23:59:59";}/*** 获取本周的第一天* @return String* **/public static String getWeekStart(){Calendar cal=Calendar.getInstance();cal.add(Calendar.WEEK_OF_MONTH, 0);cal.set(Calendar.DAY_OF_WEEK, 2);Date time=cal.getTime();return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 00:00:00";}/*** 获取本周的最后一天* @return String* **/public static String getWeekEnd(){Calendar cal=Calendar.getInstance();cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));cal.add(Calendar.DAY_OF_WEEK, 1);Date time=cal.getTime();return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 23:59:59";}/*** 获取本年的第一天* @return String* **/public static String getYearStart(){return new SimpleDateFormat("yyyy").format(new Date())+"-01-01";}/*** 获取本年的最后一天* @return String* **/public static String getYearEnd(){Calendar calendar = Calendar.getInstance();calendar.set(Calendar.MONTH,calendar.getActualMaximum(Calendar.MONTH));calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));Date currYearLast = calendar.getTime();return new SimpleDateFormat("yyyy-MM-dd").format(currYearLast)+" 23:59:59";}
}

Maps:这个类就是方便放键值对的,我觉得比较方便

/**
* @author wang hongyu
* @package_name signalsys-parent
* @date 2021/6/10
*/
public class Maps {private Maps() {}public static <K, V> HashMap<K, V> newHashMap() {return new HashMap<K, V>(100);}public static <K, V> HashMap<K, V> newHashMap(K k, V v) {HashMap<K, V> map = new HashMap<K, V>(100);map.put(k, v);return map;}@SuppressWarnings("unchecked")public static <K, V> HashMap<K, V> newHashMap(K k, V v,Object... extraKeyValues) {if (extraKeyValues.length % 2 != 0) {throw new IllegalArgumentException();}HashMap<K, V> map = new HashMap<K, V>(100);map.put(k, v);for (int i = 0; i < extraKeyValues.length; i += 2) {k = (K) extraKeyValues[i];v = (V) extraKeyValues[i + 1];map.put(k, v);}return map;}
}
  1. 导出代码,实际我觉得如果没有太复杂的业务我觉得这个可以套用在别的导出功能的实现上。createExcel
 /*** 根据模板创建excel文件* @param template excel模板* @param fileName 导出的文件名称* @param data  excel中填充的数据* @return*/public File createExcel(String template, String fileName, Map<String, Object> data){FileOutputStream outputStream = null;String filePath = "c:/excleLoad";String dir = "c:/excleLoad";if (!new File(dir).exists()) {new File(dir).mkdirs();}File file = new File(filePath + File.separator+fileName+ UUID.randomUUID().toString()+".xlsx");try {// 定义输出类型outputStream =new FileOutputStream(file);JxlsHelper jxlsHelper = JxlsHelper.getInstance();String templateFile = getClass().getClassLoader().getResource(template).getPath();InputStream is = new BufferedInputStream(new FileInputStream(templateFile));Transformer transformer = jxlsHelper.createTransformer(is, outputStream);Context context = new Context();for (Map.Entry<String, Object> entry : data.entrySet()) {context.putVar(entry.getKey(), entry.getValue());}JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator) transformer.getTransformationConfig().getExpressionEvaluator();Map<String, Object> funcs = new HashMap<String, Object>(4);funcs.put("utils", new XlsUtils());evaluator.getJexlEngine().setFunctions(funcs);jxlsHelper.processTemplate(context, transformer);} catch (Exception e) {e.printStackTrace();} finally {try {outputStream.flush();outputStream.close();} catch (Exception e) {e.printStackTrace();}}return file;}

之后就是模板的定义了。
模板里面最重要的就是表格第一行第一列的注释,它标识了我们要编辑的区域。不然会找不到咱们模板里的表达式。

jx:area(lastCell="H7")

点击Shift+F2就会弹出来让你编辑注释。然后把上面的代码复制进去就可以了。
对应单个属性的导出的时候,我们可以直接这样写

咱们不是通过map给表格数据的么,所以response--是我传到表格里面的key
timeTableInstanceBaseVO--是对象的名字
timeTableTitle--是属性名称
${response.timeTableInstanceBaseVO.timeTableTitle}

下面的是怎么在表格上做格式化的:
在这个方法里:public File createExcel(String template, String fileName, Map<String, Object> data)

Map<String, Object> funcs = new HashMap<String, Object>(4);
funcs.put("utils", new XlsUtils());evaluator.getJexlEngine().setFunctions(funcs);

这个段代码结合上下问看看,可以全文所有看看我这个在哪用的。
下面的代码是这个里的,主要的意思就是给了一个格式化的工具类。就是我上面XlsUtils具体怎么在excel中的表达式里面用呢?
如下:

${utils:handleTrainPlanCode(data.scheduleTitle,data.trainPlanTitle)}
简单是说明一下:
utils:是一传的键
handleTrainPlanCode:是你自己定义的格式化的方法
data.scheduleTitle,data.trainPlanTitle:这两个是我自己的参数,至于这个data是什么我在下面再说,就类似for循环中遍历用的变量。
如何导出列表数据

在你想导出列表位置的那一列,编辑注释
jx:each(items="response.trainPlanActualVOS" var="data" lastCell="I7")
jx:each:遍历标签
items:要遍历的集合
var:遍历的变量item
lastcell:规定识别表达式的区域
模板位置
SpringBoot的项目的就放在Template下面就行。

Jxls表格导出功能帮助文档相关推荐

  1. 导出到word文档--带有表格

    有位网友说导出到word文档时原来的表格样式没有了,我认为是你在导出到word时没有设置word样式,之前我没有导出到word的太多经验,Excel导入导出是做了些,呵呵^_^ 下面给个导出到word ...

  2. 用Itext把数据导出到Pdf文档

    工夫不负有心人!先用POI实现了把数据导出为Excel,现在又实现了用Itext把数据导出为Pdf文档.因为这些技术是以前都没有接触的,而现在又都基本掌握了,所以心里略有一些成就感.现把完整程序代码列 ...

  3. 支持将数据导出到Excel文档的时候设置单元格格式的.NET控件Spire.DataExport

    Spire.DataExport for .NET是e-iceblue公司推出的一款数据导出类.NET控件.作为一款专业的数据导出控件,Spire.DataExport for .NET可以帮助开发人 ...

  4. html页面导出文件大小,【实战】通过 JS 将 HTML 导出为 PDF 文档

    背景介绍 某带道术用量确示常构端析以要效开的用,近不老人院信息管理系统项目,甲方要求将财务模块的各种报表导出为PDF文档,方便打印要圈器是天的年编功小还久概据含直这请框结业未商屏页屏随会维气大机域页效 ...

  5. 基于xdocreport导出复杂word文档,专业避坑指南

    如果你要先问我为什么要导出word?那么请你走开,你个杠精! 在完成这个功能时花费了大量的时间查阅资料,发现能满足导出复杂word文档的工具只有xdocreport,如果有其他的工具欢迎分享.废话不多 ...

  6. 如何将Revit明细表导出为Excel文档

    Revit软件没有将明细表直接导出为Excel电子表格的功能,Revit只能将明细表导出为TXT格式,但是这种TXT文件用EXCEL处理软件打开然后另存为XLS格式即可,以Revit2013版自带的建 ...

  7. 如何在PowerDesigner将PDM导出生成WORD文档或者html文件

    a)         使用PowerDesigner打开pdm文件 b)         点击Report Temlates 制作模板 点击PowerDesigner菜单栏"Report&q ...

  8. 怎么将excel表格转换成word文档

    怎么将excel表格转换成word文档?有时候为了工作需要将excel转换成word文档,但是却不知道使用什么工具,下面就简单说一下将excel表格转换成word文档的方法. 1.进行文件之间的转换首 ...

  9. js将html转为word文档,js将html导出到word文档(含echarts图表)

    需求 在开发项目途中遇到了一个需求,就是将一个整个HTML界面导出到word文档,其中包含了echarts图表,经过一番折腾,终于完成了~~~(鸡肋),过程中用到了几个插件,总结了一下几个步骤,希望可 ...

最新文章

  1. HDU 2094 产生冠军
  2. 英雄联盟显示服务器连接异常 即将退出,win7系统玩英雄联盟提示服务器连接异常即将退出...
  3. 公钥密码--Paillier
  4. ubuntu下eclipse新建项目没有java project的解决办法
  5. SAP常见的几个接口技术的区别
  6. 使用apache模块rewrite_module
  7. linux 本地yum 恢复,Linux_RHEL系统恢复安装光盘中的yum更新源的方法,安装光盘本地YUM更新源挂载安 - phpStudy...
  8. JFreeChart(三)之条形图
  9. autotools使用
  10. PyQt5和Python的多线程
  11. ATL之深入浅出书评(转)
  12. ARM SMMU的原理与IOMMU
  13. shoppingResult 客户端结算
  14. IT农民工如何来美国工作
  15. 推荐下加拿大使用的虚拟信用卡
  16. swagger csrf 404_从0岁用到8岁的404页夫人独家超实用中英文双面闪卡素材包
  17. 苹果官网是怎么实现的?(一)
  18. ffmpeg 命令参数详解
  19. 2015年阿里、网易、中兴、华为、美团等Java研发工程师面试心得
  20. Wondershare PDFelement 8 Pro Mac(PDF编辑工具)

热门文章

  1. 直接双击启动tomcat中的startup.bat闪退
  2. 一些与软件测试相关的英文网站
  3. 2020字节跳动数据库面试题及答案(二)—— NoSQL部分
  4. mobx在react中应用_借助React Native Elements,Jest和MobX MST可以轻松实现现实世界中的ReactNative应用...
  5. 将ueditor上传的视频转换为flowplayer播放,并隐藏其播放地址
  6. 【VulnHub靶场】Hackable: III
  7. SaltStack -----(三)Grains的应用
  8. RPC框架:从原理到选型,一文带你搞懂RPC
  9. MockMVC测试上传文件功能
  10. 使用http-server开启本地静态资源服务