我试图创建一个 PDF 查看器并通过将项目(文本、图像)插入到我们应用程序的 PDF 上的确切 x 和 y 坐标来修改它。我使用 react-native-pdf 查看 pdf @skynetcmg47/react-native-drag-resize 来拖动和调整大小,并使用 react-native-pdf-lib 来修改/插入文本、图像.. 我试过 pdf- lib 来修改 pdf 但在 android 的发布模式上有问题。PDFDocument.load(pdfArrayBuffer) "this.bytes.slice(start, end) undefined" 并导致更改为 react-native-pdf-lib 但没有获取 PDF 大小的选项。
基础参考:
https://medium.com/alameda-dev/react-native-pdf-digital-signature-b63e12cdc714
代码:
doneSet = async (page, x, y) => {
let newX = x;
let newY = y;
if (Platform.OS == 'ios') {
newX = x ? !DeviceInfo.isTablet() ? this.state.pageWidth * (x - 12) / Dimensions.get("window").width : x : 0;
newY = y ? !DeviceInfo.isTablet() ? (this.state.pageHeight - (this.state.pageHeight * (y + 12)) / hp('90%')) : this.state.pageHeight - y : 0;
console.log(this.state.pageWidth, this.state.pageHeight, newX, newY, x, y, this.state.pageHeight - y)
} else {
newX = x ? !DeviceInfo.isTablet() ? (this.state.pageWidth * x) / this.state.pageWidth : x : 0;
newY = y ? !DeviceInfo.isTablet() ? (this.state.pageHeight - ((this.state.pageHeight * y) / this.state.pageHeight)) - 25 : this.state.pageHeight - y : 0;
console.log(this.state.pageWidth, this.state.pageHeight, newX, newY, x, y)
}
if (this.state.pdfEditMode) {
this.setState({ pdfEditMode: false }, () => { });
const page1 = PDFPage
.modify(page - 1)
.drawImage(this.state.signaturePath, 'png', {
x: newX, // <- X coordinate location
y: newY, // <- Y coordinate location
width: this.state.signatureW,
height: this.state.signatureH
});
PDFDocument
.modify(this.state.filePath)
.modifyPages(page1)
.write()
.then(data => {
RNFS.readFile(data, "base64").then((contents) => {
let previousDocumentCopy = this.state.previousDocument;
previousDocumentCopy.push({ filePath: data, pdfBase64: contents, pdfArrayBuffer: this._base64ToArrayBuffer(contents) });
this.setState({ filePath: data, pdfBase64: contents, pdfArrayBuffer: this._base64ToArrayBuffer(contents), documentIndex: previousDocumentCopy.length - 1, nextDocument: [], previewDocument: previousDocumentCopy, xValue: 0, yValue: 0, cxValue: 0, cyValue: 0, signatureW: 100, signatureH: 100 })
})
});
}
}
render() {
return(
<SafeAreaView style={{ flex: 1}}>
<View style={{ flex: 1 }}>
{this.state.filePath ?
<View style={{ flex: 1 }}>
<Pdf
minScale={1.0}
maxScale={1.0}
scale={1.0}
spacing={0}
fitPolicy={2}
enablePaging={true}
onTouchStart={(e) => {
console.log('touchMove', e.nativeEvent);
if (this.state.pdfEditMode) {
this.setState({ showDraggrable: false, cxValue: e.nativeEvent.locationX, cyValue: e.nativeEvent.locationY, xValue: e.nativeEvent.locationX, yValue: e.nativeEvent.locationY }, () => {
setTimeout(() => {
this.setState({ showDraggrable: true, })
}, 0)
})
}
}}
usePDFKit={false}
source={{ uri: `data:application/pdf;base64,${this.state.pdfBase64}` }}
onLoadComplete={(numberOfPages, filePath, { width, height }) => { this.setPageWH(width, height) }}
onPageChanged={(page, numberOfPages) => {
console.log(`current page: ${page}`);
this.setState({ pageNumber: page });
}}
onError={(error) => {
console.log(error);
}}
onPressLink={(uri) => {
console.log(`Link presse: ${uri}`)
}}
// onPageSingleTap={(page, x, y) => {
// console.log(x, y)
// this.handleSingleTap(page, x, y);
// }}
style={styles.pdf}
/>
{this.state.pdfEditMode && this.state.signaturePath && this.state.showDraggrable ? <DragResizeBlock isResizable isDraggable x={this.state.cxValue} y={this.state.cyValue} w={this.state.signatureW} h={this.state.signatureH}
onDragEnd={this._dragRelease}
onResize={this._resizeStart}
onResizeEnd={this._resizeRelease}
connectors={['tl', 'tr', 'br', 'bl', 'c']} >
<View style={{ width: '100%', height: '100%', alignContent: 'center', alignItems: 'center' }}>
<View style={{ flexDirection: 'row', alignItems: 'center', zIndex: 10, position: 'absolute', top: 0, right: 0, backgroundColor: '#FFFFFF' }}>
<TouchableOpacity style={[styles.message,]} onPress={this.removeSignature}>
<Icon type={'FontAwesome5'} name={'trash'} style={{ fontSize: hp('1.8%'), margin: 3, color: '#d9534f' }} />
</TouchableOpacity>
<TouchableOpacity style={[styles.message,]} onPress={() => this.doneSet(this.state.pageNumber, this.state.xValue, this.state.yValue)}>
<Icon type={'FontAwesome5'} name={'check-circle'} style={{ fontSize: hp('1.8%'), margin: 3, color: '#5cb85c' }} />
</TouchableOpacity>
</View>
<FastImage
source={{ uri: `data:image/png;base64,${this.state.signatureBase64}` }}
style={{ aspectRatio: 4 / 3, width: '100%', height: '100%', }}
resizeMode={FastImage.resizeMode.cover} />
</View>
</DragResizeBlock> : null}
</View> : null}
</View>
</SafeAreaView>
)
}
库版本:
"react": "16.6.3",
"react-native": "0.58.1",
"react-native-pdf": "^5.1.7",
"rn-fetch-blob": "^0.10.15",
"react-native-pdf-lib": "^1.0.0",
"@skynetcmg47/react-native-drag-resize": "^1.0.3",