React Nodejs - jsx 中的自定义@font-face 用于生成 PDF
React Nodejs - Custom @font-face in jsx for PDF generation
我有一个 React 项目,其中部分功能涉及向运行 PhantomJS 和 html-pdf
插件的 Nodejs 服务器发送请求,以创建一个 pdf,该 pdf 通过我的 React 组件构建节点服务器。我遇到的问题实际上是将自定义字体嵌入到我的反应组件中。我有一个 base64 编码的字体集,与一堆文件相比,它更容易包含,但由于 React 在 CSS 中的加载方式,我不断收到错误。
这是在我的 NodeJS 服务器上调用以生成 PDF 的函数:
exports.order = (req, res, next) => {
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
// page.viewportSize = { width: 600, height: 600 };
page.open(`http://localhost:3005/print/work/${req.params.id}`).then(function(status) {
page.property('content').then(function(content) {
pdf.create(content, options).toBuffer(function(err, buffer){
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename=order-${req.params.id}.pdf`,
'Content-Length': buffer.length
});
res.end(buffer);
});
page.close();
ph.exit();
});
});
});
});
}
这是包含 PDF HTML 的实际 React 组件:
var React = require('react');
var moment = require('moment');
class PrintWorkOrder extends React.Component {
render() {
var order = this.props;
var s = {
body: {
width: '100%',
float: 'none',
fontFamily: 'Helvetica',
color: '#000',
display: 'block',
fontSize: 10,
}
}
return (
<div style={s.body}>
I shortened the content in her for brevity
</div>
)
}
}
module.exports = PrintWorkOrder;
该功能目前有效,只是现在我需要添加一些不是 Helvetica 的自定义字体,我在使用当前实现解决这个问题时遇到了问题。有人对此有任何见解吗?
我也有同样的问题,我做的是将front编码成base64,然后把它写成
font.css
@font-face {
font-family: 'fontName';
src: url(data:application/x-font-woff;charset=utf-8;base64,<base64>) format('woff'),
font-weight: normal;
font-style: normal;
}
诀窍是读取 CSS 文件内容并将其作为样式标签注入 DOM 标记
React.createElement('style', { dangerouslySetInnerHTML: { __html: this.props.children } });
所以要这样做:
对于第二行代码,它创建样式元素的作用。你可以做的是编写一个组件,从 .css 文件中读取内容,然后将内容放入样式元素中,如下所示:
Style.js
var React = require('react');
export default class Style extends React.Component {
static propTypes = {
children: React.PropTypes.string.isRequired
};
render() {
return React.createElement('style', { dangerouslySetInnerHTML: { __html: this.props.children } });
}
}
修改PrintWorkOrder.js
var React = require('react');
var moment = require('moment');
var fs = require('fs');
var path = require('path');
var Style = require('./Style');
const readFile = (filePath) => fs.readFileSync(path.resolve(__dirname, filePath)).toString();
class PrintWorkOrder extends React.Component {
constructor(props) {
super(props);
this.state = {
styles: []
}
}
componentWillMount() {
this.setState({
styles: [
readFile('font.css') // Assuming putting font.css same location with PrintWorkOrder component
]
})
}
render() {
var order = this.props;
var s = {
body: {
width: '100%',
float: 'none',
fontFamily: 'Helvetica',
color: '#000',
display: 'block',
fontSize: 10,
}
}
return (
<html>
<head>
{/* Here to render all the styles */}
{this.state.styles.map(s => (<Style>{s}</Style>))}
</head>
<body>
<div style={s.body}>
I shortened the content in her for brevity
</div>
</body>
</html>
);
}
}
module.exports = PrintWorkOrder;
我有一个 React 项目,其中部分功能涉及向运行 PhantomJS 和 html-pdf
插件的 Nodejs 服务器发送请求,以创建一个 pdf,该 pdf 通过我的 React 组件构建节点服务器。我遇到的问题实际上是将自定义字体嵌入到我的反应组件中。我有一个 base64 编码的字体集,与一堆文件相比,它更容易包含,但由于 React 在 CSS 中的加载方式,我不断收到错误。
这是在我的 NodeJS 服务器上调用以生成 PDF 的函数:
exports.order = (req, res, next) => {
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
// page.viewportSize = { width: 600, height: 600 };
page.open(`http://localhost:3005/print/work/${req.params.id}`).then(function(status) {
page.property('content').then(function(content) {
pdf.create(content, options).toBuffer(function(err, buffer){
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename=order-${req.params.id}.pdf`,
'Content-Length': buffer.length
});
res.end(buffer);
});
page.close();
ph.exit();
});
});
});
});
}
这是包含 PDF HTML 的实际 React 组件:
var React = require('react');
var moment = require('moment');
class PrintWorkOrder extends React.Component {
render() {
var order = this.props;
var s = {
body: {
width: '100%',
float: 'none',
fontFamily: 'Helvetica',
color: '#000',
display: 'block',
fontSize: 10,
}
}
return (
<div style={s.body}>
I shortened the content in her for brevity
</div>
)
}
}
module.exports = PrintWorkOrder;
该功能目前有效,只是现在我需要添加一些不是 Helvetica 的自定义字体,我在使用当前实现解决这个问题时遇到了问题。有人对此有任何见解吗?
我也有同样的问题,我做的是将front编码成base64,然后把它写成
font.css
@font-face {
font-family: 'fontName';
src: url(data:application/x-font-woff;charset=utf-8;base64,<base64>) format('woff'),
font-weight: normal;
font-style: normal;
}
诀窍是读取 CSS 文件内容并将其作为样式标签注入 DOM 标记
React.createElement('style', { dangerouslySetInnerHTML: { __html: this.props.children } });
所以要这样做: 对于第二行代码,它创建样式元素的作用。你可以做的是编写一个组件,从 .css 文件中读取内容,然后将内容放入样式元素中,如下所示:
Style.js
var React = require('react');
export default class Style extends React.Component {
static propTypes = {
children: React.PropTypes.string.isRequired
};
render() {
return React.createElement('style', { dangerouslySetInnerHTML: { __html: this.props.children } });
}
}
修改PrintWorkOrder.js
var React = require('react');
var moment = require('moment');
var fs = require('fs');
var path = require('path');
var Style = require('./Style');
const readFile = (filePath) => fs.readFileSync(path.resolve(__dirname, filePath)).toString();
class PrintWorkOrder extends React.Component {
constructor(props) {
super(props);
this.state = {
styles: []
}
}
componentWillMount() {
this.setState({
styles: [
readFile('font.css') // Assuming putting font.css same location with PrintWorkOrder component
]
})
}
render() {
var order = this.props;
var s = {
body: {
width: '100%',
float: 'none',
fontFamily: 'Helvetica',
color: '#000',
display: 'block',
fontSize: 10,
}
}
return (
<html>
<head>
{/* Here to render all the styles */}
{this.state.styles.map(s => (<Style>{s}</Style>))}
</head>
<body>
<div style={s.body}>
I shortened the content in her for brevity
</div>
</body>
</html>
);
}
}
module.exports = PrintWorkOrder;