Merge pull request #2 from dolanmiu/master

merge from origin
This commit is contained in:
wangfengming
2020-06-20 20:05:20 +08:00
committed by GitHub
14 changed files with 247 additions and 34 deletions

55
demo/53-chinese.ts Normal file
View File

@ -0,0 +1,55 @@
// Chinese text - Chinese text need to use a Chinese font. And ascii text need to use a ascii font.
// Different from the `52-japanese.ts`.
// `52-japanese.ts` will set all characters to use Japanese font.
// `53-chinese.ts` will set Chinese characters to use Chinese font, and set ascii characters to use ascii font.
// Note that if the OS have not install `KaiTi` font, this demo doesn't work.
// Import from 'docx' rather than '../build' if you install from npm
import * as fs from "fs";
import { Document, HeadingLevel, Packer, Paragraph, TextRun } from "../build";
const doc = new Document({
styles: {
paragraphStyles: [
{
id: "Normal",
name: "Normal",
basedOn: "Normal",
next: "Normal",
quickFormat: true,
run: {
font: {
ascii: "Times",
eastAsia: "KaiTi",
},
},
},
],
},
});
doc.addSection({
children: [
new Paragraph({
text: "中文和英文 Chinese and English",
heading: HeadingLevel.HEADING_1,
}),
new Paragraph({
text: "中文和英文 Chinese and English",
}),
new Paragraph({
children: [
new TextRun({
text: "中文和英文 Chinese and English",
font: { eastAsia: "SimSun" }, // set eastAsia to "SimSun".
// The ascii characters will use the default font ("Times") specified in paragraphStyles
}),
],
}),
],
});
Packer.toBuffer(doc).then((buffer) => {
fs.writeFileSync("My Document.docx", buffer);
});

View File

@ -26,7 +26,7 @@ const name = new TextRun({
- `emphasisMark({type="dot"})`: Set the emphasis mark style
- `color(color)`: Set the text color, using 6 hex characters for RRGGBB (no leading `#`)
- `size(halfPts)`: Set the font size, measured in half-points
- `font(name)`: Set the run's font
- `font(name)` or `font({ascii, cs, eastAsia, hAnsi, hint})`: Set the run's font
- `style(name)`: Apply a named run style
- `characterSpacing(value)`: Set the character spacing adjustment (in TWIPs)

View File

@ -1,6 +1,6 @@
{
"name": "docx",
"version": "5.1.1",
"version": "5.2.0",
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
"main": "build/index.js",
"scripts": {

View File

@ -417,7 +417,7 @@ describe("AbstractNumbering", () => {
});
});
it("#font", () => {
it("#font by name", () => {
const abstractNumbering = new AbstractNumbering(1, [
{
level: 0,
@ -447,6 +447,37 @@ describe("AbstractNumbering", () => {
});
});
it("#font for ascii and eastAsia", () => {
const abstractNumbering = new AbstractNumbering(1, [
{
level: 0,
format: "lowerRoman",
text: "%0.",
style: {
run: {
font: {
ascii: "Times",
eastAsia: "KaiTi",
},
},
},
},
]);
const tree = new Formatter().format(abstractNumbering);
expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({
"w:rPr": [
{
"w:rFonts": {
_attr: {
"w:ascii": "Times",
"w:eastAsia": "KaiTi",
},
},
},
],
});
});
it("#bold", () => {
const abstractNumbering = new AbstractNumbering(1, [
{

View File

@ -3,7 +3,7 @@ import { Attributes, XmlComponent } from "file/xml-components";
export { Underline } from "./underline";
export { EmphasisMark } from "./emphasis-mark";
export { SubScript, SuperScript } from "./script";
export { RunFonts } from "./run-fonts";
export { RunFonts, IFontAttributesProperties } from "./run-fonts";
export class Bold extends XmlComponent {
constructor() {

View File

@ -21,5 +21,12 @@ describe("RunFonts", () => {
},
});
});
it("uses the font attrs for ascii and eastAsia", () => {
const tree = new Formatter().format(new RunFonts({ ascii: "Times", eastAsia: "KaiTi" }));
expect(tree).to.deep.equal({
"w:rFonts": { _attr: { "w:ascii": "Times", "w:eastAsia": "KaiTi" } },
});
});
});
});

View File

@ -1,14 +1,14 @@
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
interface IRunFontAttributesProperties {
readonly ascii: string;
readonly cs: string;
readonly eastAsia: string;
readonly hAnsi: string;
export interface IFontAttributesProperties {
readonly ascii?: string;
readonly cs?: string;
readonly eastAsia?: string;
readonly hAnsi?: string;
readonly hint?: string;
}
class RunFontAttributes extends XmlAttributeComponent<IRunFontAttributesProperties> {
class RunFontAttributes extends XmlAttributeComponent<IFontAttributesProperties> {
protected readonly xmlKeys = {
ascii: "w:ascii",
cs: "w:cs",
@ -19,16 +19,26 @@ class RunFontAttributes extends XmlAttributeComponent<IRunFontAttributesProperti
}
export class RunFonts extends XmlComponent {
constructor(ascii: string, hint?: string) {
constructor(name: string, hint?: string);
constructor(attrs: string | IFontAttributesProperties);
constructor(nameOrAttrs: string | IFontAttributesProperties, hint?: string) {
super("w:rFonts");
if (typeof nameOrAttrs === "string") {
// use constructor(name: string, hint?: string);
const name = nameOrAttrs;
this.root.push(
new RunFontAttributes({
ascii: ascii,
cs: ascii,
eastAsia: ascii,
hAnsi: ascii,
ascii: name,
cs: name,
eastAsia: name,
hAnsi: name,
hint: hint,
}),
);
} else {
// use constructor(attrs: IRunFontAttributesProperties);
const attrs = nameOrAttrs;
this.root.push(new RunFontAttributes(attrs));
}
}
}

View File

@ -275,6 +275,32 @@ describe("Run", () => {
],
});
});
it("should set the font for ascii and eastAsia", () => {
const run = new Run({
font: {
ascii: "Times",
eastAsia: "KaiTi",
},
});
const tree = new Formatter().format(run);
expect(tree).to.deep.equal({
"w:r": [
{
"w:rPr": [
{
"w:rFonts": {
_attr: {
"w:ascii": "Times",
"w:eastAsia": "KaiTi",
},
},
},
],
},
],
});
});
});
describe("#color", () => {

View File

@ -27,11 +27,16 @@ import {
import { NumberOfPages, NumberOfPagesSection, Page } from "./page-number";
import { RunProperties } from "./properties";
import { Text } from "./run-components/text";
import { RunFonts } from "./run-fonts";
import { IFontAttributesProperties, RunFonts } from "./run-fonts";
import { SubScript, SuperScript } from "./script";
import { Style } from "./style";
import { Underline, UnderlineType } from "./underline";
interface IFontOptions {
readonly name: string;
readonly hint?: string;
}
export interface IRunOptions {
readonly bold?: true;
readonly italics?: true;
@ -52,10 +57,7 @@ export interface IRunOptions {
readonly subScript?: boolean;
readonly superScript?: boolean;
readonly style?: string;
readonly font?: {
readonly name: string;
readonly hint?: string;
};
readonly font?: IFontOptions | IFontAttributesProperties;
readonly highlight?: string;
readonly shading?: {
readonly type: ShadingType;
@ -140,7 +142,11 @@ export class Run extends XmlComponent {
}
if (options.font) {
if ("name" in options.font) {
this.properties.push(new RunFonts(options.font.name, options.font.hint));
} else {
this.properties.push(new RunFonts(options.font));
}
}
if (options.highlight) {

View File

@ -1,6 +1,6 @@
import { Size, SizeComplexScript } from "file/paragraph/run/formatting";
import { RunProperties } from "file/paragraph/run/properties";
import { RunFonts } from "file/paragraph/run/run-fonts";
import { IFontAttributesProperties, RunFonts } from "file/paragraph/run/run-fonts";
import { XmlComponent } from "file/xml-components";
export class RunPropertiesDefaults extends XmlComponent {
@ -18,8 +18,8 @@ export class RunPropertiesDefaults extends XmlComponent {
return this;
}
public font(fontName: string): RunPropertiesDefaults {
this.properties.push(new RunFonts(fontName));
public font(font: string | IFontAttributesProperties): RunPropertiesDefaults {
this.properties.push(new RunFonts(font));
return this;
}
}

View File

@ -1,4 +1,11 @@
import { AlignmentType, EmphasisMarkType, IIndentAttributesProperties, ISpacingProperties, UnderlineType } from "../paragraph";
import {
AlignmentType,
EmphasisMarkType,
IFontAttributesProperties,
IIndentAttributesProperties,
ISpacingProperties,
UnderlineType,
} from "../paragraph";
import { ShadingType } from "../table";
export interface IRunStyleOptions {
@ -19,7 +26,7 @@ export interface IRunStyleOptions {
readonly type?: EmphasisMarkType;
};
readonly color?: string;
readonly font?: string;
readonly font?: string | IFontAttributesProperties;
readonly characterSpacing?: number;
readonly highlight?: string;
readonly shadow?: {

View File

@ -202,7 +202,7 @@ describe("CharacterStyle", () => {
});
});
it("should add font", () => {
it("should add font by name", () => {
const style = new CharacterStyle({
id: "myStyleId",
run: {
@ -241,6 +241,46 @@ describe("CharacterStyle", () => {
});
});
it("should add font for ascii and eastAsia", () => {
const style = new CharacterStyle({
id: "myStyleId",
run: {
font: {
ascii: "test font ascii",
eastAsia: "test font eastAsia",
},
},
});
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{
"w:rPr": [
{
"w:rFonts": {
_attr: {
"w:ascii": "test font ascii",
"w:eastAsia": "test font eastAsia",
},
},
},
],
},
{
"w:uiPriority": {
_attr: {
"w:val": 99,
},
},
},
{
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
});
it("should add character spacing", () => {
const style = new CharacterStyle({
id: "myStyleId",

View File

@ -1,6 +1,7 @@
import { EmphasisMarkType } from "file/paragraph/run/emphasis-mark";
import * as formatting from "file/paragraph/run/formatting";
import { RunProperties } from "file/paragraph/run/properties";
import { IFontAttributesProperties } from "file/paragraph/run/run-fonts";
import { UnderlineType } from "file/paragraph/run/underline";
import { BasedOn, Link, SemiHidden, UiPriority, UnhideWhenUsed } from "./components";
@ -28,7 +29,7 @@ export interface IBaseCharacterStyleOptions {
readonly type?: EmphasisMarkType;
};
readonly color?: string;
readonly font?: string;
readonly font?: string | IFontAttributesProperties;
readonly characterSpacing?: number;
readonly highlight?: string;
readonly shadow?: {

View File

@ -484,7 +484,7 @@ describe("ParagraphStyle", () => {
});
});
it("#font", () => {
it("#font by name", () => {
const style = new ParagraphStyle({
id: "myStyleId",
run: {
@ -513,6 +513,36 @@ describe("ParagraphStyle", () => {
});
});
it("#font for ascii and eastAsia", () => {
const style = new ParagraphStyle({
id: "myStyleId",
run: {
font: {
ascii: "Times",
eastAsia: "KaiTi",
},
},
});
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{
"w:rPr": [
{
"w:rFonts": {
_attr: {
"w:ascii": "Times",
"w:eastAsia": "KaiTi",
},
},
},
],
},
],
});
});
it("#bold", () => {
const style = new ParagraphStyle({
id: "myStyleId",