NativeScript 中的原生工作表
NativeScript 是一个移动应用框架。它构建使用 JavaScript 来描述布局和事件的 iOS 和 Android 应用。
¥NativeScript is a mobile app framework. It builds iOS and Android apps that use JavaScript for describing layouts and events.
SheetJS 是一个用于从电子表格读取和写入数据的 JavaScript 库。
¥SheetJS is a JavaScript library for reading and writing data from spreadsheets.
该演示使用 NativeScript 和 SheetJS 来处理和生成电子表格。我们将探讨如何在 NativeScript 应用中加载 SheetJS;解析并生成存储在设备上的电子表格;并获取和解析远程文件。
¥This demo uses NativeScript and SheetJS to process and generate spreadsheets. We'll explore how to load SheetJS in a NativeScript app; parse and generate spreadsheets stored on the device; and fetch and parse remote files.
"完整示例" 创建一个应用,如下图所示:
¥The "Complete Example" creates an app that looks like the screenshots below:
iOS | Android |
---|---|
讨论内容涵盖 NativeScript + Angular 集成。假定熟悉 Angular 和 TypeScript。
¥The discussion covers the NativeScript + Angular integration. Familiarity with Angular and TypeScript is assumed.
本 demo 在以下环境下进行了测试:
¥This demo was tested in the following environments:
真实设备
¥Real Devices
OS | 设备 | NS | 日期 |
---|---|---|---|
安卓 30 | 英伟达盾 | 8.7.2 | 2024-06-09 |
iOS 15.1 | iPad Pro | 8.7.2 | 2024-06-09 |
模拟器
¥Simulators
OS | 设备 | NS | 开发平台 | 日期 |
---|---|---|---|---|
安卓 34 | 像素 3a | 8.7.2 | darwin-arm | 2024-06-09 |
iOS 17.5 | iPhone SE(第 3 代) | 8.7.2 | darwin-arm | 2024-06-09 |
安卓 34 | 像素 3a | 8.6.5 | win10-x64 | 2024-04-07 |
在开始此演示之前,请手动禁用遥测。
¥Before starting this demo, manually disable telemetry.
NativeScript 8.6.1 将遥测分为两部分:"usage" 和 "error"。两者都必须单独禁用:
¥NativeScript 8.6.1 split the telemetry into two parts: "usage" and "error". Both must be disabled separately:
npx -p nativescript ns usage-reporting disable
npx -p nativescript ns error-reporting disable
要验证遥测是否已禁用:
¥To verify telemetry was disabled:
npx -p nativescript ns usage-reporting status
npx -p nativescript ns error-reporting status
集成详情
¥Integration Details
SheetJS NodeJS 模块 可以从应用中的任何组件或脚本导入。
¥The SheetJS NodeJS Module can be imported from any component or script in the app.
@nativescript/core/file-system
包提供了用于文件访问的类。File
类不支持二进制数据,但 @nativescript/core
的文件访问单例支持读写 ArrayBuffer
数据。
¥The @nativescript/core/file-system
package provides classes for file access.
The File
class does not support binary data, but the file access singleton
from @nativescript/core
does support reading and writing ArrayBuffer
data.
读取和写入数据需要 URL。以下代码片段在典型文档文件夹中搜索指定的文件名:
¥Reading and writing data require a URL. The following snippet searches typical document folders for a specified filename:
import { Folder, knownFolders, path } from '@nativescript/core/file-system';
function get_url_for_filename(filename: string): string {
const target: Folder = knownFolders.documents() || knownFolders.ios.sharedPublic();
return path.normalize(target.path + "///" + filename);
}
应用配置
¥App Configuration
出于隐私考虑,应用必须请求文件访问权限。有用于访问数据的特殊 API,并且在未来的平台版本中可能会发生变化。
¥Due to privacy concerns, apps must request file access. There are special APIs for accessing data and are subject to change in future platform versions.
Technical Details (click to show)
Android
Android security has evolved over the years. In newer Android versions, the following workarounds were required:
READ_EXTERNAL_STORAGE
andWRITE_EXTERNAL_STORAGE
allow apps to access files outside of the app scope. These are required for scoped storage access.
When the demo was last tested, this option was enabled by default.
android:requestLegacyExternalStorage="true"
enabled legacy behavior in some older releases.
The manifest is saved to App_Resources/Android/src/main/AndroidManifest.xml
:
<application
android:requestLegacyExternalStorage="true"
android:name="com.tns.NativeScriptApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:hardwareAccelerated="true">
- Permissions must be explicitly requested.
@nativescript-community/perms
is a community module for managing permissions:
import { request } from '@nativescript-community/perms';
import { File } from '@nativescript/core/file-system';
Storage access must be requested before writing data:
/* request permissions */
const res = await request('storage');
The external paths can be resolved using the low-level APIs:
/* find Downloads folder */
const dl_dir = android.os.Environment.DIRECTORY_DOWNLOADS;
const dl = android.os.Environment.getExternalStoragePublicDirectory(dl_dir).getAbsolutePath();
/* write to file */
File.fromPath(dl + "/SheetJSNS.xls").writeSync(data);
读取本地文件
¥Reading Local Files
getFileAccess().readBufferAsync
可以将数据读入 ArrayBuffer
对象。SheetJS read
方法 [^1] 可以将此数据解析为工作簿对象。[^2]
¥getFileAccess().readBufferAsync
can read data into an ArrayBuffer
object.
The SheetJS read
method[^1] can parse this data into a workbook object.[^2]
import { getFileAccess } from '@nativescript/core';
import { read } from 'xlsx';
/* find appropriate path */
const url = get_url_for_filename("SheetJSNS.xls");
/* get data */
const ab: ArrayBuffer = await getFileAccess().readBufferAsync(url);
/* read workbook */
const wb = read(ab);
解析成工作簿后,sheet_to_json
[^3] 方法可以生成行数据对象:
¥After parsing into a workbook, the sheet_to_json
[^3] method can generate row
data objects:
import { utils } from 'xlsx';
/* grab first sheet */
const wsname: string = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
/* generate array of row objects */
const data = utils.sheet_to_json(ws);
写入本地文件
¥Writing Local Files
带有选项 type: "binary"
的 SheetJS write
方法 [^4] 将生成 Uint8Array
对象。getFileAccess().writeBufferAsync
可以将数据从 Uint8Array
对象写入设备。
¥The SheetJS write
method[^4] with the option type: "binary"
will generate
Uint8Array
objects. getFileAccess().writeBufferAsync
can write data from a
Uint8Array
object to the device.
iOS 直接支持 Uint8Array
,但 Android 需要一个真正的数字数组:
¥iOS supports Uint8Array
directly but Android requires a true array of numbers:
import { getFileAccess } from '@nativescript/core';
import { write } from 'xlsx';
/* find appropriate path */
const url = get_url_for_filename("SheetJSNS.xls");
/* generate Uint8Array */
const u8: Uint8Array = write(wb, { bookType: 'xls', type: 'binary' });
/* attempt to save Uint8Array to file */
await getFileAccess().writeBufferAsync(url, global.isAndroid ? (Array.from(u8) as any) : u8);
可以使用 SheetJS json_to_sheet
方法 [^5] 从行对象数组生成工作表。生成数组后,book_new
和 book_append_sheet
方法 [^6] 可以创建工作簿。
¥A worksheet can be generated from an array of row objects with the SheetJS
json_to_sheet
method[^5]. After generating an array, the book_new
and
book_append_sheet
methods[^6] can create the workbook.
获取远程文件
¥Fetching Remote Files
getFile
可以从 @nativescript/core/http
下载文件。将文件存储在临时文件夹中后,getFileAccess().readBufferAsync
可以读取数据,SheetJS read
方法 [^7] 可以解析该文件:
¥getFile
from @nativescript/core/http
can download files. After storing the
file in a temporary folder, getFileAccess().readBufferAsync
can read the data
and the SheetJS read
method[^7] can parse the file:
import { knownFolders, path, getFileAccess } from '@nativescript/core'
import { getFile } from '@nativescript/core/http';
import { read } from 'xlsx';
/* generate temporary path for the new file */
const temp: string = path.join(knownFolders.temp().path, "pres.xlsx");
/* download file */
const file = await getFile("https://xlsx.nodejs.cn/pres.xlsx", temp)
/* get data */
const ab: ArrayBuffer = await getFileAccess().readBufferAsync(file.path);
/* read workbook */
const wb = read(ab);
完整示例
¥Complete Example
平台配置
¥Platform Configuration
-
禁用遥测:
¥Disable telemetry:
npx -p nativescript ns usage-reporting disable
npx -p nativescript ns error-reporting disable
-
请遵循官方环境设置说明 [^8]。
¥Follow the official Environment Setup instructions[^8].
上次测试演示时,Android API 的最新版本是 34。NativeScript 不支持该 API 级别。npx -p nativescript ns doctor ios
中的确切错误消息明确说明了支持的版本:
¥When the demo was last tested, the latest version of the Android API was 34.
NativeScript did not support that API level. The exact error message from
npx -p nativescript ns doctor ios
clearly stated supported versions:
✖ No compatible version of the Android SDK Build-tools are installed on your system. You can install any version in the following range: '>=23 <=33'.
SDK 平台 Android 13.0 ("Tiramisu")
与 NativeScript 兼容。在 NativeScript 正确支持 API 级别 34 之前,必须使用 "Tiramisu"。这需要从 Android Studio 安装以下软件包:
¥The SDK Platform Android 13.0 ("Tiramisu")
was compatible with NativeScript.
Until NativeScript properly supports API level 34, "Tiramisu" must be used.
This requires installing the following packages from Android Studio:
-
Android 13.0 ("Tiramisu")
API 级别33
¥
Android 13.0 ("Tiramisu")
API Level33
-
Android SDK Build-Tools
版本33.0.2
¥
Android SDK Build-Tools
Version33.0.2
-
测试 Android 开发的本地系统配置:
¥Test the local system configuration for Android development:
npx -p nativescript ns doctor android
在上次 macOS 测试中,显示了以下输出:
¥In the last macOS test, the following output was displayed:
Expected output (click to hide)
✔ Getting environment information
No issues were detected. ✔ Your ANDROID_HOME environment variable is set and points to correct directory. ✔ Your adb from the Android SDK is correctly installed. ✔ The Android SDK is installed. ✔ A compatible Android SDK for compilation is found. ✔ Javac is installed and is configured properly. ✔ The Java Development Kit (JDK) is installed and is configured properly. ✔ Getting NativeScript components versions information... ✔ Component nativescript has 8.7.2 version and is up to date.
-
测试 iOS 开发的本地系统配置(仅限 macOS):
¥Test the local system configuration for iOS development (macOS only):
npx -p nativescript ns doctor ios
在上次 macOS 测试中,显示了以下输出:
¥In the last macOS test, the following output was displayed:
Expected output (click to hide)
✔ Getting environment information
No issues were detected. ✔ Xcode is installed and is configured properly. ✔ xcodeproj is installed and is configured properly. ✔ CocoaPods are installed. ✔ CocoaPods update is not required. ✔ CocoaPods are configured properly. ✔ Your current CocoaPods version is newer than 1.0.0. ✔ Python installed and configured correctly. ✔ Xcode version 15.4.0 satisfies minimum required version 10. ✔ Getting NativeScript components versions information... ✔ Component nativescript has 8.7.2 version and is up to date.
基础项目
¥Base Project
-
创建一个 NativeScript + Angular 应用框架:
¥Create a skeleton NativeScript + Angular app:
npx -p nativescript ns create SheetJSNS --ng
-
在 Android 模拟器中启动应用以验证应用:
¥Launch the app in the android simulator to verify the app:
cd SheetJSNS
npx -p nativescript ns run android
(可能还要等一下)
¥(this may take a while)
模拟器启动并显示测试应用后,选择终端并按 CTRL+C 结束脚本。在 Windows 上,如果提示输入 Terminate batch job
,请键入 y
并按 Enter。
¥Once the simulator launches and the test app is displayed, end the script by
selecting the terminal and pressing CTRL+C. On Windows, if
prompted to Terminate batch job
, type y
and press Enter.
如果模拟器未运行,nativescript
可能会失败并显示以下消息:
¥If the emulator is not running, nativescript
may fail with the message:
Emulator start failed with: No emulator image available for device identifier 'undefined'.
添加 SheetJS
¥Add SheetJS
本节的目标是显示 SheetJS 库版本号。
¥The goal of this section is to display the SheetJS library version number.
-
从项目文件夹中,安装 SheetJS NodeJS 模块:
¥From the project folder, install the SheetJS NodeJS module:
npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
-
编辑
src/app/item/items.component.ts
,以便组件导入 SheetJS 版本字符串并将其添加到组件中的version
变量中:¥Edit
src/app/item/items.component.ts
so that the component imports the SheetJS version string and adds it to aversion
variable in the component:
import { version } from 'xlsx';
import { Component, OnInit } from '@angular/core'
// ...
export class ItemsComponent implements OnInit {
items: Array<Item>
version = `SheetJS - ${version}`;
constructor(private itemService: ItemService) {}
// ...
-
编辑模板
src/app/item/items.component.html
以在操作栏标题中引用version
:¥Edit the template
src/app/item/items.component.html
to referenceversion
in the title of the action bar:
<ActionBar [title]="version"></ActionBar>
<GridLayout>
<!-- ... -->
-
结束脚本并在 Android 模拟器中重新启动应用:
¥End the script and relaunch the app in the Android simulator:
npx -p nativescript ns run android
标题栏应显示版本。
¥The title bar should show the version.
本地文件
¥Local Files
-
将导入和导出按钮添加到模板中:
¥Add the Import and Export buttons to the template:
<ActionBar [title]="version"></ActionBar>
<StackLayout>
<StackLayout orientation="horizontal">
<Button text="Import File" (tap)="import()" style="padding: 10px"></Button>
<Button text="Export File" (tap)="export()" style="padding: 10px"></Button>
</StackLayout>
<ListView [items]="items">
<!-- ... -->
</ListView>
</StackLayout>
-
在组件脚本中添加
import
和export
方法:¥Add the
import
andexport
methods in the component script:
import { version, utils, read, write } from 'xlsx';
import { Dialogs, getFileAccess } from '@nativescript/core';
import { Folder, knownFolders, path } from '@nativescript/core/file-system';
import { Component, OnInit } from '@angular/core'
import { Item } from './item'
import { ItemService } from './item.service'
function get_url_for_filename(filename: string): string {
const target: Folder = knownFolders.documents() || knownFolders.ios.sharedPublic();
return path.normalize(target.path + "///" + filename);
}
@Component({
selector: 'ns-items',
templateUrl: './items.component.html',
})
export class ItemsComponent implements OnInit {
items: Array<Item>
version: string = `SheetJS - ${version}`;
constructor(private itemService: ItemService) {}
ngOnInit(): void {
this.items = this.itemService.getItems()
}
/* Import button */
async import() {
}
/* Export button */
async export() {
}
}
-
结束脚本并在 Android 模拟器中重新启动应用:
¥End the script and relaunch the app in the Android simulator:
npx -p nativescript ns run android
标题下方应出现两个按钮:
¥Two buttons should appear just below the header:
-
通过添加高亮的行来实现导入和导出:
¥Implement import and export by adding the highlighted lines:
/* Import button */
async import() {
/* find appropriate path */
const url = get_url_for_filename("SheetJSNS.xls");
try {
await Dialogs.alert(`Attempting to read from SheetJSNS.xls at ${url}`);
/* get data */
const ab: ArrayBuffer = await getFileAccess().readBufferAsync(url);
/* read workbook */
const wb = read(ab);
/* grab first sheet */
const wsname: string = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
/* update table */
this.items = utils.sheet_to_json<Item>(ws);
} catch(e) { await Dialogs.alert(e.message); }
}
/* Export button */
async export() {
/* find appropriate path */
const url = get_url_for_filename("SheetJSNS.xls");
try {
/* create worksheet from data */
const ws = utils.json_to_sheet(this.items);
/* create workbook from worksheet */
const wb = utils.book_new();
utils.book_append_sheet(wb, ws, "Sheet1");
/* generate Uint8Array */
const u8: Uint8Array = write(wb, { bookType: 'xls', type: 'buffer' });
/* attempt to save Uint8Array to file */
await getFileAccess().writeBufferAsync(url, global.isAndroid ? (Array.from(u8) as any) : u8);
await Dialogs.alert(`Wrote to SheetJSNS.xls at ${url}`);
} catch(e) { await Dialogs.alert(e.message); }
}
安卓
¥Android
-
在 Android 模拟器中启动应用:
¥Launch the app in the Android Simulator:
npx -p nativescript ns run android
如果应用没有自动启动,请手动打开 SheetJSNS
应用。
¥If the app does not automatically launch, manually open the SheetJSNS
app.
-
点击 "导出文件"。将出现一个对话框,打印文件的写入位置。通常 URL 是
/data/user/0/org.nativescript.SheetJSNS/files/SheetJSNS.xls
¥Tap "Export File". A dialog will print where the file was written. Typically the URL is
/data/user/0/org.nativescript.SheetJSNS/files/SheetJSNS.xls
-
从模拟器中提取文件。应在新终端或 PowerShell 窗口中运行以下命令:
¥Pull the file from the simulator. The following commands should be run in a new terminal or PowerShell window:
adb root
adb pull /data/user/0/org.nativescript.SheetJSNS/files/SheetJSNS.xls SheetJSNS.xls
如果模拟器无法获得 root 权限,则以下命令在 macOS 中有效:
¥If the emulator cannot be rooted, the following command works in macOS:
adb shell "run-as org.nativescript.SheetJSNS cat /data/user/0/org.nativescript.SheetJSNS/files/SheetJSNS.xls" > SheetJSNS.xls
-
使用电子表格编辑器打开
SheetJSNS.xls
。¥Open
SheetJSNS.xls
with a spreadsheet editor.
在标题行之后,插入一行,其中单元格 A2 = 0、B2 = SheetJS、C2 = Library:
¥After the header row, insert a row with cell A2 = 0, B2 = SheetJS, C2 = Library:
id | name | role
0 | SheetJS | Library
1 | Ter Stegen | Goalkeeper
3 | Piqué | Defender
...
-
将文件推回模拟器:
¥Push the file back to the simulator:
adb push SheetJSNS.xls /data/user/0/org.nativescript.SheetJSNS/files/SheetJSNS.xls
如果模拟器无法获得 root 权限,则以下命令在 macOS 中有效:
¥If the emulator cannot be rooted, the following command works in macOS:
dd if=SheetJSNS.xls | adb shell "run-as org.nativescript.SheetJSNS dd of=/data/user/0/org.nativescript.SheetJSNS/files/SheetJSNS.xls"
-
点击 "导入文件"。一个对话框将打印所读取文件的路径。列表中的第一项将会更改。
¥Tap "Import File". A dialog will print the path of the file that was read. The first item in the list will change.
iOS
iOS 测试只能在运行 macOS 的 Apple 硬件上执行!
¥iOS testing can only be performed on Apple hardware running macOS!
Xcode 和 iOS 模拟器在 Windows 或 Linux 上不可用。
¥Xcode and iOS simulators are not available on Windows or Linux.
向下滚动到 "获取文件" 以进行 Android 设备测试。
¥Scroll down to "Fetching Files" for Android device testing.
-
在 iOS 模拟器中启动应用:
¥Launch the app in the iOS Simulator:
npx -p nativescript ns run ios
-
点击 "导出文件"。将出现一个对话框,打印文件的写入位置。
¥Tap "Export File". A dialog will print where the file was written.
-
使用电子表格编辑器打开该文件。
¥Open the file with a spreadsheet editor.
在标题行之后,插入一行,其中单元格 A2 = 0、B2 = SheetJS、C2 = Library:
¥After the header row, insert a row with cell A2 = 0, B2 = SheetJS, C2 = Library:
id | name | role
0 | SheetJS | Library
1 | Ter Stegen | Goalkeeper
3 | Piqué | Defender
...
-
保存文件后重新启动应用。
¥Restart the app after saving the file.
-
点击 "导入文件"。一个对话框将打印所读取文件的路径。列表中的第一项将更改:
¥Tap "Import File". A dialog will print the path of the file that was read. The first item in the list will change:
获取文件
¥Fetching Files
-
在
src/app/item/items.component.ts
中,使ngOnInit
异步:¥In
src/app/item/items.component.ts
, makengOnInit
asynchronous:
async ngOnInit(): Promise<void> {
this.items = await this.itemService.getItems()
}
-
将
item.service.ts
替换为以下内容:¥Replace
item.service.ts
with the following:
import { Injectable } from '@angular/core'
import { knownFolders, path, getFileAccess } from '@nativescript/core'
import { getFile } from '@nativescript/core/http';
import { read, utils } from 'xlsx';
import { Item } from './item'
interface IPresident { Name: string; Index: number };
@Injectable({ providedIn: 'root' })
export class ItemService {
private items: Array<Item>;
async getItems(): Promise<Array<Item>> {
/* fetch https://xlsx.nodejs.cn/pres.xlsx */
const temp: string = path.join(knownFolders.temp().path, "pres.xlsx");
const ab = await getFile("https://xlsx.nodejs.cn/pres.xlsx", temp)
/* read the temporary file */
const wb = read(await getFileAccess().readBufferAsync(ab.path));
/* translate the first worksheet to the required Item type */
const data = utils.sheet_to_json<IPresident>(wb.Sheets[wb.SheetNames[0]]);
return this.items = data.map((pres, id) => ({id, name: pres.Name, role: ""+pres.Index} as Item));
}
getItem(id: number): Item {
return this.items.filter((item) => item.id === id)[0]
}
}
-
结束脚本并在 Android 模拟器中重新启动应用:
¥End the script and relaunch the app in the Android simulator:
npx -p nativescript ns run android
该应用应显示总统数据。
¥The app should show Presidential data.
安卓设备
¥Android Device
-
使用 USB 电缆连接 Android 设备。
¥Connect an Android device using a USB cable.
如果设备要求允许 USB 调试,请点击 "允许"。
¥If the device asks to allow USB debugging, tap "Allow".
-
关闭所有 Android/iOS 模拟器。
¥Close any Android / iOS emulators.
-
在 Android 应用中启用 "传统外部存储"。清单存储在
App_Resources/Android/src/main/AndroidManifest.xml
:¥Enable "Legacy External Storage" in the Android app. The manifest is stored at
App_Resources/Android/src/main/AndroidManifest.xml
:
<application
android:requestLegacyExternalStorage="true"
android:name="com.tns.NativeScriptApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:hardwareAccelerated="true">
-
安装
@nativescript-community/perms
依赖:¥Install the
@nativescript-community/perms
dependency:
npm i --save @nativescript-community/perms
-
将高亮的行添加到
items.component.ts
:¥Add the highlighted lines to
items.component.ts
:
-
从 NativeScript 核心导入
File
,从新依赖导入request
:¥Import
File
from NativeScript core andrequest
from the new dependency:
import { Dialogs, getFileAccess, Utils } from '@nativescript/core';
import { request } from '@nativescript-community/perms';
import { Folder, knownFolders, path, File } from '@nativescript/core/file-system';
import { Component, OnInit } from '@angular/core'
// ...
-
在
export
方法中添加一个新的写操作:¥Add a new write operation to the
export
method:
/* attempt to save Uint8Array to file */
await getFileAccess().writeBufferAsync(url, global.isAndroid ? (Array.from(u8) as any) : u8);
await Dialogs.alert(`Wrote to SheetJSNS.xls at ${url}`);
if(global.isAndroid) {
/* request permissions */
const res = await request('storage');
/* write to Downloads folder */
const dl = android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
File.fromPath(dl + "/SheetJSNS.xls").writeSync(Array.from(u8));
}
} catch(e) { await Dialogs.alert(e.message); }
-
构建 APK 并在设备上运行:
¥Build APK and run on device:
npx -p nativescript ns run android
如果 Android 模拟器已关闭并且 Android 设备已连接,则最后一个命令将构建 APK 并安装在设备上。
¥If the Android emulators are closed and an Android device is connected, the last command will build an APK and install on the device.
Android Device Testing (click to hide)
当应用启动时,如果加载了 SheetJS 库并且设备已连接到互联网,则应显示总统列表。
¥When the app launches, if the SheetJS library is loaded and if the device is connected to the Internet, a list of Presidents should be displayed.
点击 "导出文件"。该应用将显示警报。点击 "OK"。
¥Tap "Export File". The app will show an alert. Tap "OK".
切换到 "文件" 应用并打开 "下载" 文件夹。应该有一个名为 SheetJSNS.xls
.txt 的新文件。
¥Switch to the "Files" app and open the "Downloads" folder. There should be a new
file named SheetJSNS.xls
.
iOS 设备
¥iOS Device
-
使用 USB 线连接 iOS 设备
¥Connect an iOS device using a USB cable
-
关闭所有 Android/iOS 模拟器。
¥Close any Android / iOS emulators.
-
启用开发者代码签名证书:
¥Enable developer code signing certificates:
在 Xcode 中打开 platforms/ios/SheetJSNS.xcodeproj/project.xcworkspace
。选择 "项目导航器",然后选择 "应用" 项目。在主视图中,选择 "签名和能力"。在 "签名" 下,在下拉菜单中选择一个团队。
¥Open platforms/ios/SheetJSNS.xcodeproj/project.xcworkspace
in Xcode. Select
the "Project Navigator" and select the "App" project. In the main view, select
"Signing & Capabilities". Under "Signing", select a team in the dropdown menu.
-
在设备上运行:
¥Run on device:
npx -p nativescript ns run ios
iOS Device Testing (click to hide)
当应用启动时,如果加载了 SheetJS 库并且设备已连接到互联网,则应显示总统列表。
¥When the app launches, if the SheetJS library is loaded and if the device is connected to the Internet, a list of Presidents should be displayed.
点击 "导出文件"。该应用将显示警报。点击 "OK"。
¥Tap "Export File". The app will show an alert. Tap "OK".
切换到 "文件" 应用并打开 "下载" 文件夹。应该有一个名为 SheetJSNS.xls
.txt 的新文件。
¥Switch to the "Files" app and open the "Downloads" folder. There should be a new
file named SheetJSNS.xls
.
[^1]: 见 read
于 "读取文件"
[^2]: 见 "工作簿对象"
¥See "Workbook Object"
[^3]: 见 sheet_to_json
于 "实用工具"
¥See sheet_to_json
in "Utilities"
[^4]: 见 write
于 "写入文件"
[^5]: 见 json_to_sheet
于 "实用工具"
¥See json_to_sheet
in "Utilities"
[^6]: 有关 book_new
和 book_append_sheet
的详细信息,请参阅 "工作簿助手" 于 "实用工具"。
¥See "Workbook Helpers" in "Utilities" for details on book_new
and book_append_sheet
.
[^7]: 见 read
于 "读取文件"
[^8]: 请参阅 NativeScript 文档中的 "本地设置"。对于 Windows 和 Linux,请遵循 "安卓" 说明。对于 macOS,请遵循 iOS 和 Android 说明。
¥See "Local setup" in the NativeScript documentation. For Windows and Linux, follow the "Android" instructions. For macOS, follow both the iOS and Android instructions.