diff --git a/demo/jyExample.js b/demo/jyExample.js
new file mode 100644
index 0000000..4302543
--- /dev/null
+++ b/demo/jyExample.js
@@ -0,0 +1,162 @@
+/* eslint-disable no-nested-ternary,no-restricted-syntax,prefer-const,no-plusplus,max-len */
+import React, { Component } from 'react';
+import { render, Text, Document, Hr, Table } from '../src/index';
+import { TitleStyle, SubTitleStyle, HrStyle, OneTitleStyle, TableHeaderStyle, TableBodyStyle, TextStyle } from './jyStyles';
+
+const { values, entries } = Object;
+
+/**
+ * 表格
+ * @param props
+ * @returns {*}
+ * @constructor
+ */
+function TableComponent(props) {
+ const { headers, data } = props;
+ const headerDatas = [];
+ // 设置表头样式
+ headers.forEach((item) => {
+ const header = {};
+ header.value = item;
+ header.styles = TableHeaderStyle;
+ headerDatas.push(header);
+ });
+ return (
+
+ );
+}
+
+
+// 时间数据
+const dateData = { year: 2018,
+ month: 1,
+ day: 10,
+ issue: 1
+};
+
+// 表格1数据
+const table1Headers = ['监控名称', '余额', '比上日', '比上月', '比年初', '年增幅'];
+const table1Data = [['人民币', '1000.00', '1000.00', '1000.00', '1000.00', '1000.00']];
+
+// 贷款汇总
+const lnBal = { sz: 100, pj: -100, gr: 0 };
+
+// 净增Top5
+const lnAddTop5 = [{ name: '大连', value: '30' },
+ { name: '湖南省', value: '15.24' },
+ { name: '厦门', value: '9.26' },
+ { name: '湖北省', value: '7.05' },
+ { name: '河南省', value: '7.04' }];
+
+// 回落Top5
+const lnReduceTop5 = [{ name: '上海市', value: '-12.1' },
+ { name: '江西省', value: '-11.74' },
+ { name: '山东省', value: '-9.26' },
+ { name: '天津市', value: '-7.05' },
+ { name: '陕西省', value: '-7.04' }];
+
+// 表格2
+const table2Headers = [{ value: '省', styles: { ...TableHeaderStyle } },
+ { value: '客户', styles: { ...TableHeaderStyle } },
+ { value: '金额', styles: { ...TableHeaderStyle } },
+ { value: '行业', styles: { ...TableHeaderStyle } }];
+let table2Data = [['湖南省', '张三', '1000.00', '互联网']];
+
+const lnTrade = { count: 3000, amt: 189.12, count5000: 15 };
+
+class MyDocument extends Component {
+ // 副标题
+ subTitle() {
+ const { date } = this.props;
+ // 生成填充空格
+ const tab = ' '.repeat(60);
+ // 生成文本
+ return `${date.year}年${date.month}月${date.day}日${tab}第${date.issue}期`;
+ }
+
+ // 一级标题1
+ oneTitle1() {
+ const { date } = this.props;
+ return `一、${date.month}月${date.day}日境内机构数据摘要:`;
+ }
+
+ // 名字和金额映射
+ nameAndValue(topValue) {
+ let str = '';
+ topValue.forEach((item) => {
+ if (str === '') {
+ str = `${item.name}(${(item.value >= 0) ? `+${item.value}` : `${item.value}`})`;
+ } else {
+ str = `${str}、${item.name}(${(item.value >= 0) ? `+${item.value}` : `${item.value}`})`;
+ }
+ });
+ return str;
+ }
+
+ // 第一段
+ text1() {
+ const { date, lnBal, lnAddTop5, lnReduceTop5 } = this.props;
+
+ // 汇总
+ let [a, d, r] = [0, 0, 0];
+ for (let bal of values(lnBal)) {
+ (bal > 0) ? a++ : (bal === 0) ? d++ : r++;
+ }
+ const numMap = new Map([[1, '一'], [2, '二'], [3, '三']]); // 数字与汉字映射
+ let lnTotal = `${(a > 0) ? `${numMap.get(a)}升` : ''}${
+ (d > 0) ? `${numMap.get(d)}平` : ''}${
+ (r > 0) ? `${numMap.get(r)}降` : ''}`;
+
+ // 各项贷款
+ const lnName = new Map([['sz', 'XXXX款'], ['pj', 'XXXX款'], ['gr', 'XXXX款']]);
+ for (let [key, bal] of entries(lnBal)) {
+ lnTotal = `${lnTotal},${lnName.get(key)}${
+ (bal > 0) ? `增加${bal}亿元` : ''}${
+ (bal === 0) ? '持平' : ''}${
+ (bal < 0) ? `减少${Math.abs(bal)}亿元` : ''}`;
+ }
+
+ let str = ` ${date.month}月${date.day}日,`;
+ str = `${str}境内机构XXXX款、XXXX款、XXXX款较上日表现为${lnTotal}。`;
+ str = `${str}XXXX款是${this.nameAndValue(lnAddTop5)},`;
+ str = `${str}较上月末回落较多的省分别是${this.nameAndValue(lnReduceTop5)}。`;
+ return str;
+ }
+
+ // 一级标题2
+ oneTitle2() {
+ const { date } = this.props;
+ return `二、${date.month}月${date.day}日发放情况:`;
+ }
+
+ // 第二段
+ text2() {
+ const { lnTrade } = this.props;
+ let str = ` 境内累计发放${lnTrade.count}笔,金额${lnTrade.amt}亿元。`;
+ str = `${str}5000万元(含)以上发放${lnTrade.count5000}笔,具体见下表。`;
+ return str;
+ }
+
+
+ render() {
+ return (
+
+ 交易情况
+ {this.subTitle()}
+
+ {this.oneTitle1()}
+
+ {this.text1()}
+ {this.oneTitle2()}
+ {this.text2()}
+
+
+ );
+ }
+}
+
+render(, `${__dirname}/jy.docx`);
+
diff --git a/demo/jyStyles.js b/demo/jyStyles.js
new file mode 100644
index 0000000..81cc085
--- /dev/null
+++ b/demo/jyStyles.js
@@ -0,0 +1,47 @@
+// 标题样式
+const TitleStyle = {
+ fontSize: 22,
+ fontFace: '方正小标宋_GBK'
+};
+// 副标题
+const SubTitleStyle = {
+ fontSize: 14,
+ fontFace: '仿宋_GB2312'
+};
+// 横线
+const HrStyle = {
+ // 样式未实现
+};
+// 一级标题
+const OneTitleStyle = {
+ fontSize: 14,
+ fontFace: '仿宋_GB2312',
+ bold: true
+};
+// 表格头
+const TableHeaderStyle = {
+ bold: true,
+ size: 21
+};
+// 表格体
+const TableBodyStyle = {
+ tableColWidth: 4261, // Width of each column
+ tableSize: 21, // 字体大小
+ tableAlign: 'right', // 表格居右
+ borders: true
+};
+// 正文
+const TextStyle = {
+ fontSize: 14,
+ fontFace: '仿宋_GB2312'
+};
+
+export {
+ TitleStyle,
+ SubTitleStyle,
+ HrStyle,
+ OneTitleStyle,
+ TableHeaderStyle,
+ TableBodyStyle,
+ TextStyle
+};
diff --git a/src/components/Bullet.js b/src/components/Bullet.js
index 1c5e95d..60356da 100644
--- a/src/components/Bullet.js
+++ b/src/components/Bullet.js
@@ -9,7 +9,6 @@ class BulletItem extends Root {
super(root, props);
this.root = root;
this.props = props;
- this.adder = this.root.doc.createListOfDots();
}
appendChild(child) {
@@ -22,6 +21,7 @@ class BulletItem extends Root {
}
async renderChildren(align, styles) {
+ this.adder = this.root.doc.createListOfDots();
await renderNodes(align, null, styles, this.adder, this.children, this.props);
}
diff --git a/src/components/Document.js b/src/components/Document.js
index 4b0c3bb..80df2f5 100644
--- a/src/components/Document.js
+++ b/src/components/Document.js
@@ -4,7 +4,7 @@ import { applyStyles } from '../styles/styles';
/**
* This component wraps all the children (string, components) and renders them.
* It only takes two props, 'align' for alignment of the document and 'info' for adding
- * document information like name of the author and description of the document.
+ * document information like name of the author and description of the document.
*/
class Document {
@@ -14,10 +14,7 @@ class Document {
constructor(root, props) {
this.root = root;
this.props = props;
- // Create a new paragraph
- this.adder = this.root.doc.createP();
- // Align the children which are of type string
- this.adder.options.align = this.props.align;
+
// Add document information
Object.assign(this.root.doc.options, this.props.info ? this.props.info : {});
// Validate the component props
@@ -36,6 +33,10 @@ class Document {
async renderChildren() {
for (let i = 0; i < this.children.length; i += 1) {
if (typeof this.children[i] === 'string') {
+ // Create a new paragraph
+ this.adder = this.root.doc.createP();
+ // Align the children which are of type string
+ this.adder.options.align = this.props.align;
// If not a component, render it as a paragraph
await this.adder.addText(
this.children[i], this.props.style ? applyStyles(this.props.style) : {},
diff --git a/src/components/HOC.js b/src/components/HOC.js
index bfe9ade..e92d695 100644
--- a/src/components/HOC.js
+++ b/src/components/HOC.js
@@ -12,7 +12,6 @@ function hoc(component, fn) {
constructor(root, props) {
this.root = root;
this.props = props;
- this.adder = fn === 'getHeader' ? this.root.doc.getHeader().createP() : this.root.doc.getFooter().createP();
}
appendChild(child) {
@@ -25,6 +24,7 @@ function hoc(component, fn) {
}
async renderChildren(align, styles) {
+ this.adder = fn === 'getHeader' ? this.root.doc.getHeader().createP() : this.root.doc.getFooter().createP();
await renderNodes(align, this.props.align, styles, this.adder, this.children, this.props);
}
diff --git a/src/components/Image.js b/src/components/Image.js
index 2b71660..2815085 100644
--- a/src/components/Image.js
+++ b/src/components/Image.js
@@ -19,7 +19,14 @@ class Image extends Root {
}
async renderImage(align) {
- this.adder = this.root.doc.createP();
+ // ҳü־
+ if (this.props.headFootFlag === 'head') {
+ this.adder = this.root.doc.getHeader().createP();
+ } else if (this.props.headFootFlag === 'foot') {
+ this.adder = this.root.doc.getFooter().createP();
+ } else {
+ this.adder = this.root.doc.createP();
+ }
// Align the image with context by Document or through component prop 'align'
alignChildren(this.adder, align, this.props.align);
diff --git a/src/components/Number.js b/src/components/Number.js
index e3fd318..7587cbf 100644
--- a/src/components/Number.js
+++ b/src/components/Number.js
@@ -9,7 +9,6 @@ class NumberItem extends Root {
super(root, props);
this.root = root;
this.props = props;
- this.adder = this.root.doc.createListOfNumbers();
}
appendChild(child) {
@@ -22,6 +21,7 @@ class NumberItem extends Root {
}
async renderChildren(align, styles) {
+ this.adder = this.root.doc.createListOfNumbers();
await renderNodes(align, null, styles, this.adder, this.children, this.props);
}
diff --git a/src/components/PageBreak.js b/src/components/PageBreak.js
index bbbd9ed..a9a94d7 100644
--- a/src/components/PageBreak.js
+++ b/src/components/PageBreak.js
@@ -7,11 +7,11 @@ class PageBreak extends Root {
constructor(root, props) {
super(root, props);
this.root = root;
- this.adder = this.root.doc.putPageBreak();
}
async render() {
- await this.adder;
+
+ await this.root.doc.putPageBreak();
}
}
diff --git a/src/components/Text.js b/src/components/Text.js
index 727fa98..447710c 100644
--- a/src/components/Text.js
+++ b/src/components/Text.js
@@ -14,7 +14,6 @@ class Text extends Root {
super(root, props);
this.root = root;
this.props = props;
- this.adder = this.root.doc.createP();
validateTextProps(this.props);
}
@@ -62,8 +61,21 @@ class Text extends Root {
}
async renderChildren(align, styles) {
+ // 创建操作对象应该在回调函数进行,在构造方法中创建会导致和其他类型组件一起排版
+ // createP should be in a renderChildren function,
+ // In the constructor to create leads to typeset together with other types of components
+ this.adder = this.root.doc.createP();
+ // 对齐
alignChildren(this.adder, align, this.props.align);
+ // 段首缩进firstLine:'240'
+ // 段前间距spacing.before
+ // 段后间距spacing.after
+ // 行间距spacing.line
+ // docx.createP ({firstLine:'240', spacing : {before: '340', after: '330', line: '578'}});
+ this.props.firstLine && (this.adder.options.firstLine = this.props.firstLine);
+ this.props.spacing && (this.adder.options.spacing = this.props.spacing);
+
for (let i = 0; i < this.children.length; i += 1) {
if (typeof this.children[i] === 'string') {
await renderText(this.children[i], this.props, styles, this.adder);
diff --git a/src/validators/componentValidators.js b/src/validators/componentValidators.js
index 8f35f3e..46889cc 100644
--- a/src/validators/componentValidators.js
+++ b/src/validators/componentValidators.js
@@ -59,7 +59,7 @@ function validateTableProps(props) {
function headerValidators(props) {
const { headers } = props;
const headerSchema = ['value', 'styles'];
- const styleSchema = ['bold', 'size', 'color', 'align', 'vAlign', 'fontFamily', 'fill'];
+ const styleSchema = ['bold', 'size', 'color', 'align', 'vAlign', 'fontFamily', 'fill', 'cellColWidth'];
headers.forEach((header) => {
Object.keys(header).forEach((key) => {
@@ -87,7 +87,7 @@ function headerValidators(props) {
function tableStyleValidators(props) {
const { style } = props;
const styleKeys = Object.keys(style || {});
- const tableStyleSchema = ['tableColWidth', 'tableSize', 'tableColor', 'tableAlign', 'borders'];
+ const tableStyleSchema = ['tableColWidth', 'tableSize', 'tableColor', 'tableAlign', 'borders', 'tableRowHeight', 'tableRowCantSplit'];
styleKeys.forEach((key) => {
if (!tableStyleSchema.includes(key)) {
@@ -101,7 +101,7 @@ function tableStyleValidators(props) {
* @param {Object} props Component props
*/
function validateTextProps(props) {
- const knownProps = ['style', 'align', 'children'];
+ const knownProps = ['style', 'align', 'children', 'firstLine', 'spacing'];
const takesProps = Object.keys(props || {});
takesProps.forEach((prop) => {